C++ 对象并集与指针并集
如果我有两个并线结构:C++ 对象并集与指针并集,c++,c++11,C++,C++11,如果我有两个并线结构: struct A { A() {} ~A() {} union { vector<int> vi; vector<double> db; }; }; 结构A{ A(){} ~A(){} 联合{ 向量vi; 矢量分贝; }; }; 及 结构B{ 联合{ 向量*vi; 向量*db; }; }; 我明白我必须以不同的方式与他们合作,例如: A a; new (&a.vi) ve
struct A {
A() {}
~A() {}
union {
vector<int> vi;
vector<double> db;
};
};
结构A{
A(){}
~A(){}
联合{
向量vi;
矢量分贝;
};
};
及
结构B{
联合{
向量*vi;
向量*db;
};
};
我明白我必须以不同的方式与他们合作,例如:
A a;
new (&a.vi) vector<int>;
A;
新的(&a.vi)载体;
vs
B;
b、 vi=新向量();
除此之外,将第一种方法(无限制联合
)用于第二种方法(仅保留指向当前向量的指针)是否有任何优势?或者它们在功能和性能方面是相同的,唯一不同的是我如何使用它们
编辑:原始代码是没有编译的最简单示例,我在结构中添加了
A(){}
和~A(){}
,以使其正确且可编译。通常使用值或指针之间的区别是,如果使用指针,则必须管理所有权。拥有成员意味着成员类将在析构函数中自动销毁它,并在复制/移动构造函数和赋值运算符中复制它
但是,当使用不受限制的联合时,编译器不会为联合成员中非平凡的函数生成
在std::vector
的情况下,这些函数包含了几乎所有的特殊成员函数
这意味着您必须自己定义这些函数,无论您使用的是成员(因为编译器不会为您这样做)还是指针(因为如果您使用new
,指针的默认所有权不是您想要的)
明显的区别在于成员是以单独的分配方式驻留在堆上,还是驻留在对象本身中,这对于vector
s可能不那么重要,因为大多数对象都将驻留在堆上
就我个人而言,除非我有很好的理由,否则我会避免使用不受限制的联合,节省一个
向量的空间(三个指针)可能还不够好。通常使用值或指针之间的区别是,如果使用指针,就必须管理所有权。拥有成员意味着成员类将在析构函数中自动销毁它,并在复制/移动构造函数和赋值运算符中复制它
但是,当使用不受限制的联合时,编译器不会为联合成员中非平凡的函数生成
在std::vector
的情况下,这些函数包含了几乎所有的特殊成员函数
这意味着您必须自己定义这些函数,无论您使用的是成员(因为编译器不会为您这样做)还是指针(因为如果您使用new
,指针的默认所有权不是您想要的)
明显的区别在于成员是以单独的分配方式驻留在堆上,还是驻留在对象本身中,这对于vector
s可能不那么重要,因为大多数对象都将驻留在堆上
就个人而言,除非我有很好的理由,否则我会避免使用不受限制的并集,节省一个向量的空间(三个指针)可能还不够好
我在A
struct中添加了A(){}
和~A(){}
,以使其正确且可编译
添加构造函数和析构函数可以使代码可编译,但不能使其正确。原始示例中固有的问题仍然存在:编译器不知道如何处理联合后的内存
两个向量都管理自己的内存vi
管理指向int
的指针,而db
管理指向double
的指针。两个向量都放在内存中的同一位置,因此它们的指针是共享的。当分配、复制或销毁A
时,编译器不知道调用-A::vi
或A::db
的函数是谁
虽然您可以通过定义资源管理的所有特殊函数(构造函数/复制构造函数/移动构造函数/析构函数)使其正常工作,但这是一个非常重要的练习,会导致非常脆弱的代码。问题在于,每次向联合添加新成员时,代码都必须更改,但编译器无法提醒您。旧代码可以编译,但一旦分配新成员并复制包含它的联合,就会导致未定义的行为
我在A
struct中添加了A(){}
和~A(){}
,以使其正确且可编译
添加构造函数和析构函数可以使代码可编译,但不能使其正确。原始示例中固有的问题仍然存在:编译器不知道如何处理联合后的内存
两个向量都管理自己的内存vi
管理指向int
的指针,而db
管理指向double
的指针。两个向量都放在内存中的同一位置,因此它们的指针是共享的。当分配、复制或销毁A
时,编译器不知道调用-A::vi
或A::db
的函数是谁
虽然您可以通过定义资源管理的所有特殊函数(构造函数/复制构造函数/移动构造函数/析构函数)使其正常工作,但这是一个非常重要的练习,会导致非常脆弱的代码。问题在于,每次向联合添加新成员时,代码都必须更改,但编译器无法提醒您。旧代码可以编译,但一旦分配新成员并复制包含它的联合,就会导致未定义的行为。
A a;
new (&a.vi) vector<int>;
B b;
b.vi = new vector<int>();