在超类联合之上叠加子类联合

时间:2014-09-04 20:30:47

标签: c++ inheritance unions

我想知道是否可以将成员附加到子类中的C ++联合。

class A { 
    ...
    union { int a; int b; };
 };

 class B : public A {
     ...
     int c; //<- Can this use the same storage as the union?
 };

一个更具体的例子是标记联合的想法,你希望有一个子类为联合添加一个类型。

2 个答案:

答案 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。