如果我有这个怎么办:
union{
vector<int> intVec ;
vector<float> floatVec ;
vector<double> doubleVec ;
} ;
当然,我将只使用 3 个向量中的一个。但是......当所有 3 个向量都被构造时会发生什么?
3个向量的构造函数会相互干扰吗?(因为它们3在同一个内存地址中)
谢谢。
当前的 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 ) 提出了不受限制的联合,但它给 C++添加了更多的对象生命周期陷阱。
您不能拥有包含非 POD 类类型的联合。您的示例将无法编译。
您可以将boost::variant
其用作 C 联合的安全替代方案。请参阅boost.org 上的文档。但是,您可能会重新考虑您的设计并改用多态性。当然,这取决于您要完成的工作。
来自 C++ 标准,第 9.5 节:
具有非平凡构造函数 (12.1)、非平凡复制构造函数 (12.8)、非平凡析构函数 (12.4) 或非平凡复制赋值运算符 (13.5.3, 12.8) 的类的对象不能成为工会成员,
在这里,对于“非平凡”阅读“有用”:-)
3个向量的构造函数会相互干扰吗?(因为它们3在同一个内存地址中)
C++ 标准不允许你的程序,所以它(充其量!)实现定义发生了什么。
例如,如果您的实现调用所有三个默认构造函数,并且它们都分配内存,并存储指向新分配空间的指针,那么您就有内存泄漏(前两个分配被第三个覆盖)。
如果析构函数都被调用并且它们都释放了“他们的”内存,那么您将进行双重释放(实际上是三重释放);这可能会破坏分配数据结构,这是一件坏事。如果你崩溃了,你会很高兴,因为如果你不崩溃,调试起来会困难得多。
我认为这些问题可能是标准不允许这样做的原因。
(更有意义的事情可能是只默认构造第一类,但这仍然不明智,只是不那么疯狂......)
现在 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>
可以代替使用)。
一个变体被允许多次持有相同的类型,并且持有相同类型的不同的 cv 限定版本。
与聚合初始化期间联合的行为一致,默认构造的变体保留其第一个替代的值,除非该替代不是默认构造的(在这种情况下,变体也不是默认构造的)。辅助类std::monostate
可用于使此类变体默认可构造。
您可能想看看Boost.Variant可以包含不同类型的单个值。