如果我有这个:
union{
vector<int> intVec ;
vector<float> floatVec ;
vector<double> doubleVec ;
} ;
当然,我将只使用3个向量中的一个。但是......当所有3个向量都被构造时会发生什么? 3个向量的构成器会相互干扰吗? (因为它们中的3个在同一个内存地址中)
感谢。
答案 0 :(得分:16)
当前的C ++标准不允许联盟内的非POD类型。您将从gcc
:
error: member ‘std::vector<int, std::allocator<int> >
<anonymous union>::i’ with constructor not allowed in union
error: member ‘std::vector<int, std::allocator<int> >
<anonymous union>::i’ with destructor not allowed in union
新C ++标准(C++0x)建议unrestricted unions,但adds yet more object lifetime pitfalls to C++。
答案 1 :(得分:9)
您不能拥有包含非POD类类型的联合。您的样本将无法编译。
您可以使用boost::variant
作为C联盟的安全替代方案。请参阅documentation on boost.org。但是,您可能会重新考虑您的设计并使用多态。当然,取决于你想要完成的事情。
答案 2 :(得分:2)
从C ++标准,第9.5节:
带有a的类的对象 非平凡的构造函数(12.1),a 非平凡的拷贝构造函数(12.8),a 非平凡的析构函数(12.4),或者 非平凡的复制赋值运算符 (13.5.3,12.8)不能成为a的成员 工会,
这里,“非平凡”读“有用”: - )
答案 3 :(得分:2)
3个向量的推理器会相互干扰吗? (因为它们中的3个在同一个内存地址中)
C ++标准不允许你的程序,所以它(充其量!)实现 - 定义会发生什么。
例如,如果您的实现调用所有三个默认构造函数,并且所有这些构造都调用内存,并将指针存储到新分配的空间,则会发生内存泄漏(前两个分配将被第三个覆盖)。 / p>
如果所有析构函数都被调用并且它们都释放了“他们的”记忆,那么你将完成双重自由(三重,真实);这可能会破坏分配数据结构,这是一件坏事。如果你崩溃会很高兴,因为如果不这样做,那就很难调试。
我认为这些问题可能为什么标准不允许这样做。
(一个更有感觉的事情可能只是默认 - 构建第一堂课,但那仍然不是很敏感,只是不那么疯狂......)
答案 4 :(得分:1)
您可能需要查看Boost.Variant,其中可以包含不同类型的单个值。
答案 5 :(得分:1)
现在C ++标准支持变体。选中https://en.cppreference.com/w/cpp/utility/variant。
std::variant
在标题中定义
template <class... Types>
class variant;
(自C ++ 17起)
类模板std::variant
表示类型安全的union。在任何给定时间std::variant
的实例要么拥有其替代类型之一的值,要么在发生错误的情况下-没有值(这种状态很难实现,请参见valueless_by_exception)。>
与联合一样,如果变量持有某个对象类型T的值,则T的对象表示将直接在变量本身的对象表示内分配。不允许变体分配额外的(动态)内存。
不允许变体保存引用,数组或类型为void。空变量也格式不正确(可以使用std::variant<std::monostate>
)。
允许一个变体不止一次拥有相同的类型,并拥有不同的具有简历资格的相同类型的版本。
与aggregate initialization期间的联合行为一致,默认构造的变体保留其第一个替代的值,除非该替代也不是默认可构造的(在这种情况下,该变体也不是默认可构造的) 。辅助类std::monostate
可用于使此类变体默认可构造。