Union 与 static_cast(void*)
我正在编写代码,直到现在我都在使用这样的结构:
struct s{
enum Types { zero = 0, one, two };
unsigned int type;
void* data;
}
我需要一些通用结构来存储来自不同类的数据,并且我想在 std::vector 中使用它,所以这就是我不能使用模板的原因。什么是更好的选择:联合还是空指针?
空指针仅分配我需要的空间,但出于某种原因,C++ 是强类型语言,并且在我需要使用这些数据的任何地方进行强制转换并不是 C++ 代码应该设计的方式。正如我所读到的,除非别无选择,否则不应使用 void 指针。
这个替代方案可能是工会。它们随 c++ 一起提供,并为每个成员使用相同的内存空间,非常类似于 void 指针。然而它们是有代价的——分配的空间是联合中最大元素的大小,在我的例子中,大小之间的差异很大。
这是相当风格化和“正确使用语言”的问题,因为这两种方法都完成了我需要做的事情,但我无法确定良好的风格化 C++ 代码是否可以弥补浪费的内存(尽管现在的内存并不大)忧虑)。
I'm writing code and until now I was using structures like this:
struct s{
enum Types { zero = 0, one, two };
unsigned int type;
void* data;
}
I needed some generic structure to store data from different classes and I wanted to use it in std::vector, so that's reason why I can't use templates. What's better option: unions or void pointers?
Void pointer allocates only as much space as I need, but c++ is strong typed language for some reason and casting everywhere I need to use those data is not the way c++ code should be designed. As I read, void pointers shouldn't be used unless there's no alternative.
That alternative could be Unions. They comes with c++ and uses the same memory space for every member, very much like void pointers. However they come at price - allocated space is the size of largest element in union, and in my case differences between sizes are big.
This is rather stylistic and "correct language using" problem, as both ways accomplish what I need to do, but I can't decide if nicely stylized c++ code can pay for that wasted memory (even though memory these days isn't a big concern).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
考虑
boost::any
或boost::variant
在决定使用哪一个之前,请看一下比较:
希望它能帮助您做出正确的决定。选择一个,以及标准库中的任何容器来存储对象,
std::vector
、std::vector,或任何其他。
Consider
boost::any
orboost::variant
if you want to store objects of heterogeneous types.And before deciding which one to use, have a look at the comparison:
Hopefully, it will help you to make the correct decision. Choose one, and any of the container from the standard library to store the objects,
std::vector<boost::any>
,std::vector<boost::variant>
, or any other.boost::variant
。基本上,它是一个类型安全的联合,在这种情况下,联合似乎是迄今为止最合适的答案。可以使用
void*
,但这意味着动态分配,并且您必须维护Types
enum
和用于转换的表。内存限制可能使
void*
成为一个可接受的选择,但这不是“简洁”的答案,而且我不会选择它,直到boost::variant
和只是普通的union
已被证明是不可接受的。boost::variant
.Basically, it is a type-safe union, and in this case, it seems like unions are by far the most appropriate answer. A
void*
could be used, but that would mean dynamic allocation, and you would have to maintain theTypes
enum
, and the table for casting.Memory constraints could make
void*
an acceptable choice, but it's not the 'neat' answer, and I wouldn't go for it until bothboost::variant
and just a plainunion
have shown to be unacceptable.如果您的类有足够的共同点可以放入同一个容器中,请为它们提供一个带有虚拟析构函数的基类,并且可能还提供一个虚拟成员函数来检索您的类型代码,即使此时不仅dynamic_cast更合适,而且探索您的类是否没有足够的共同点来为它们提供更完整的通用接口可能是合理的。
否则,请考虑提供一个具有适当类型的数据成员的自定义容器类,以保存需要放入其中的所有不同类的实例。
If your classes have enough in common to be put in the same container give them a base class with a virtual destructor, and possibly a virtual member function to retrieve your type code, even though at that point not only dynamic_cast would be more appropriate, but it could be reasonable to explore whether your classes don't have enough in common to provide them with a more complete common interface.
Otherwise consider providing a custom container class with appropriately typed data members to hold instances of all the different classes you need to put into it.