覆盖超类并集的子类并集ontop

Overlay subclass union ontop of superclass union

本文关键字:ontop 子类 覆盖 超类      更新时间:2023-10-16

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

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

一个更具体的例子是带标签的并集的想法,其中您希望有一个向并集添加类型的子类。

你说,

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

该语言不允许扩展union。无法将成员追加到union

更糟糕的是,与可以通过创建子类(structs)来扩展的classes和structs不同,unions不能有基类。它们也不能用作基类。

首先,根据标准,9.5点1,在一个并集中,任何时候最多可以有一个非静态数据成员处于活动状态,也就是说,任何时候都可以将最多一个非静止数据成员的值存储在并集中

在您的情况下,由于c是int,向原始并集添加成员没有任何好处。只需重用一个现有的int。或者从一开始就在联合中预见所有可能的标记成员。

然而,你可以做的是将c定义为引用,并为其分配联合成员的地址,记住联合对象的所有非静态数据成员都有相同的地址(§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 << "; ";
    }
};

当然,对一名签名的现役工会成员的限制仍然有效。

顺便说一句,为什么基类和派生类之间不能共享相同的并集?因为标准上写着:

  • 除非在派生类中重新声明,否则基类的成员也被视为派生类的成员(§10第2点)

  • 具有相同访问控制的(非并集)类的非静态数据成员被分配,以便稍后的成员在类对象中具有更高的地址(§9.2 pt 13)

  • 因此派生类的成员具有比基类的成员更高的地址。

  • 但是联合对象的所有非静态数据成员都有相同的地址(§9.5/1)

  • 因此,派生类的成员不可能属于基类中的并集。QED。