【问题标题】:Adding arbitrary types to an object at runtime在运行时向对象添加任意类型
【发布时间】:2011-06-13 17:30:30
【问题描述】:

在我们的应用程序中,我们有一个在运行时接收属性的对象。例如,给对象添加一个浮点数:

my_object->f("volume") = 1.0f;

检索卷的工作方式相同:

cout << my_object->f("volume") << endl;

在内部,这由字符串到其各自类型的映射表示。每种类型都有自己的访问方法和映射。它看起来像这样:

map<string, float> my_floats;
map<string, int> my_ints;
map<string, void *> my_void_pointers;

哦,可怕的void *。有时我们需要向对象添加类或函数。我们没有为每一种可能的类型都设置一个单独的地图,而是选择了void * 地图。我们遇到的问题是清理。目前,我们保留了void * 指向的每种“悬空”对象的列表,并在必要时对这些单独的列表调用清理函数。

我不喜欢必须使用void * 以及正确清理所需的所有额外注意。有没有更好的方法在运行时将任意类型存储在对象中,可以通过字符串映射访问,并且仍然受益于通过析构函数自动清理?

【问题讨论】:

  • 你看过boost::any类型吗?
  • 还没有。感谢您的链接 GWW。诚然,我并不像我应该的那样精通提升——如果你不确定要寻找什么,图书馆会有点吓人!
  • 我同意那里的文档肯定会更好

标签: c++ pointers void-pointers


【解决方案1】:

您在这里的选择被宠坏了 - boost::any 或简单地将所有内容存储为 std::string 都会立即浮现在脑海中。

【讨论】:

  • boost::any 绝对是这里的胜利。
  • @DeadMG 依赖 - 也许你不想要依赖。
  • @Neil 您能解释一下将所有内容存储为 std::string 是什么意思吗?您的意思是将类型存储为字符串,然后根据已知类型列表检查该字符串并做出相应反应?
  • @Neil:即使你不想依赖 Boost,实现也没什么大不了的。
  • @sinoth 不,我的意思是将输入数据转换为字符串和枚举类型(或类似类型),然后根据请求将其转换回来,并进行适当的错误检查。这基本上就是这类事情的所有实现所做的事情,无论是哪种方式。
【解决方案2】:

这篇文章似乎很好地回答了你的问题。

Storing a list of arbitrary objects in C++

【讨论】:

  • 谢谢!看起来 boost::variant 或 boost::any 都会做我想要的。
【解决方案3】:

与其将映射存储到这么多值,不如使用 boost::variant。毕竟,从你的界面来看,我将 int 和 float 分配给同一个字符串是不合法的。

std::map<std::string, boost::variant<float, int, std::string, ...>>;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-24
    • 2011-12-10
    • 2012-07-07
    • 2011-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多