简体   繁体   English

Union vs. static_cast(void*)

[英]Union vs. static_cast(void*)

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.我需要一些通用结构来存储来自不同类的数据,我想在 std::vector 中使用它,所以这就是我不能使用模板的原因。 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.空指针只分配我需要的空间,但出于某种原因,c++ 是强类型语言,并且在我需要使用这些数据的任何地方进行强制转换并不是 c++ 代码应该设计的方式。 As I read, void pointers shouldn't be used unless there's no alternative.正如我所读到的,除非别无选择,否则不应使用 void 指针。

That alternative could be Unions.那个替代方案可能是工会。 They comes with c++ and uses the same memory space for every member, very much like void pointers.它们随 C++ 一起提供,并为每个成员使用相同的内存空间,非常类似于 void 指针。 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).这是一个相当风格化和“正确使用语言”的问题,因为这两种方式都完成了我需要做的事情,但我无法决定风格化的 C++ 代码是否可以为浪费的内存买单(即使现在内存不是很大忧虑)。

Consider boost::any or boost::variant if you want to store objects of heterogeneous types.如果要存储异构类型的对象,请考虑boost::anyboost::variant

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.从标准库中选择一个和任何容器来存储对象, std::vector<boost::any>std::vector<boost::variant> ,或任何其他。

boost::variant . 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 the Types enum , and the table for casting.可以使用void* ,但这意味着动态分配,您必须维护Types enum和用于转换的表。

Memory constraints could make void* an acceptable choice, but it's not the 'neat' answer, and I wouldn't go for it until both boost::variant and just a plain union have shown to be unacceptable.内存限制可能使void*成为可接受的选择,但这不是“简洁”的答案,并且在boost::variant和简单的union都被证明是不可接受的之前,我不会选择它。

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.如果你的类有足够多的共同点可以放在同一个容器中,给它们一个带有虚析构函数的基类,可能还有一个虚成员函数来检索你的类型代码,即使在这一点上不仅 dynamic_cast 更合适,而且探索您的类是否没有足够的共同点来为它们提供更完整的公共接口可能是合理的。

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.否则,请考虑提供一个带有适当类型数据成员的自定义容器类,以保存您需要放入其中的所有不同类的实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM