我想知道是否可以将成员附加到子类中的C ++联合。
class A {
...
union { int a; int b; };
};
class B : public A {
...
int c; //<- Can this use the same storage as the union?
};
一个更具体的例子是标记联合的想法,你希望有一个子类为联合添加一个类型。
答案 0 :(得分:3)
你说,
我想知道是否可以将成员附加到子类中的C ++联合。
该语言不允许扩展union
。无法将成员附加到union
。
更糟糕的是,与class
es和struct
不同,可以通过创建子类(结构)来扩展,union
不能有基类。它们也可能不被用作基类。
答案 1 :(得分:2)
首先,根据标准,9.5点1,在一个联合中,最多一个非静态数据成员可以随时处于活动状态,即最多一个非值的值静态数据成员可以随时存储在联合中。
在您的情况下,由于c是int,因此将成员添加到原始联合没有任何好处。只需重用一个现有的int。或者在工会中预见所有可能的标签成员从一开始。
然而,您可以做的是将c定义为引用,并为其指定union成员的地址,请记住 union对象的所有非静态数据成员具有相同的地址(§9.5/ 1):
class B : public A {
int& c; //<- Can this use the same storage as the union?
public:
B() : c(A::a) {}
void test() {
a = 10;
std::cout << "a=" << a << "; ";
std::cout << "c=" << c << "; ";
c = 20;
std::cout << "a=" << a << "; ";
std::cout << "c=" << c << "; ";
}
};
signe积极工会成员的成员当然仍然有效。
顺便说一句,为什么不能在基类和派生类之间共享相同的联合?因为标准说:
除非在派生类中重新声明,否则基类的成员也被视为派生类的成员(§10第2点)
分配具有相同访问控制的(非联合)类的非静态数据成员,以便后面的成员在类对象中具有更高的地址。(§9.2pt 13)< / p>
因此,派生类的成员具有比基类成员更高的地址。
但联合对象的所有非静态数据成员具有相同的地址(第9.5 / 1节)
因此,派生类中的成员不可能属于基类中的联合。 QED。