c++ - 正确的 "polymorphic"方式存储枚举,有时存储一些数据

标签 c++ oop

我正在开发一个存储 std::vector 的程序点,我还加载了一个 std::unordered_map其中一些点的“约束”,然后将其应用于点数组。目前约束的形式是:

+---------------+
|Type    |Value |
+---------------+
|Constant|  1.0 |
|        |      |
|Lerp    |  n/a |
|        |      |
|Loop    |  n/a |
|        |      |
|...     |      |
+--------+------+

有几种类型,但实际上只有一种(常量)需要存储一个值(在本例中为 double 值)。在原型(prototype)中,我选择存储所有类型的值,并且只使用了 std::pair<ConstraintType, double>。 .它有效,但感觉很糟糕;虽然 Constant 是最常见的点类型,即使存储几千个未使用的 double 值在现代硬件上也可以忽略不计,但我不喜欢这种浪费。但是我想不出更好的方法。如果我从一个基类派生,据我所知,我将得到一个具有单个虚拟方法的基类(你的派生类型是什么?),然后如果它是常量,我将它向下转换并获得值.呸。我唯一想到的另一个想法就是将常量保存在一个单独的 std::unordered_map 中。 ,但是如果我添加另一个需要一个(或两个)值的约束,我该怎么办?它似乎没有规模。

我肯定在这里遗漏了一些东西,这种事情应该是微不足道的。我们将不胜感激地接受建议(我相信这将是一个重要的时刻)。

最佳答案

您可以将多态类存储为指针(例如 unique_ptr),但是您不会获得太多(因为指针将有 4 或 8 B 和另一个指向虚拟表的 4-8 B 指针,所以在 32 位应用程序上至少额外 8 B 这与每次存储 double 相同,然后它会更慢)。

至于检查,您可以通过提供(纯)虚拟 bool check(const Point &) 方法或类似方法在不进行向下转换的情况下执行此操作,这将多态地检查约束(因此约束类型可以包含任何内容并将被检查适本地)。

我还认为您可以使用 boost::any 或 boost::variant,但不幸的是,这并没有太大帮助。 boost::any 使用类型删除来保存类型,因此内部有一个指向虚拟持有者的指针(它也有一个指向虚拟表的指针)。

boost::variant 需要预先知道所有类型,这可能适用于此。然而,boost::variant 中的存储必须和它可以容纳的最大类型一样大(所以没有改进,因为每个实例基本上需要与存储 double 的最大约束相同的空间)。然而,boost::variant 的一个优点是可以在没有虚拟运行时分派(dispatch)的情况下通过使用 boost::static_visitor 完成检查,因此速度更快。

一般来说,要真正节省最大的空间量,我认为没有比在不同的列表中保留不同的约束类型(根据大小)更好的选择了。第二个最佳选择是恕我直言,使用 boost::variant,但使用指针(特定约束类型不需要多态,因此您可以节省指向虚拟表的指针所需的空间)。

关于c++ - 正确的 "polymorphic"方式存储枚举,有时存储一些数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35002999/

相关文章:

c++ - 在 linux mint 上部署 C++ wxWidgets

c++ - 无法调试 C++ eclipse makefile 项目

c++ - 从多个小部件获取分辨率

Javascript 实例变量显示为未定义

java - 我应该实现抽象类中存在的所有方法吗?

java - Intellij Idea 重构将 "getters and setters"移动到文件末尾

c++ - 如何在 OpenGL 中绘制圆弧

c++ - 我可以使用 SFINAE 检测模板类成员函数吗?

c# - 类型转换问题

c - 无法在我的 C 代码中初始化回调。不兼容的引用类型导致未定义的行为