在联合中使用继承

时间:2015-12-03 20:32:13

标签: c++ inheritance unions

我想知道是否有人知道是否可以以某种方式在联盟中使用继承。

在下面的示例中,TestFails联合不会在a结构中包含Base变量,而TestWorks确实有效。

struct Base { int a; };

union TestFails
{
    struct : public Base {};
    int b;
};

union TestWorks
{
    struct  { int a; };
    int b;
};

int main()
{
    TestWorks works;
    works.a = 0;

    TestFails fails;
    fails.a = 0;

    return 0;
}

您可以在此处测试代码:http://ideone.com/dUzpOR

3 个答案:

答案 0 :(得分:1)

首先 - 您假设TestWorks有效。 这不是标准的C ++ - 只是它的扩展 - 它被称为unnamed anonymous struct - 当你用迂腐选项编译时,你会得到:

  

prog.cc:5:27:错误:ISO C ++禁止匿名结构[-Wpedantic]
       struct:public Base {};

                       ^
  

prog.cc:11:22:错误:ISO C ++禁止匿名结构[-Wpedantic]
       struct {int a; };

要解决您的问题 - 只需命名这些匿名结构:

union TestFails
{
    struct : public Base {} s;
    //                      ^
    int b;
};

union TestWorks
{
    struct  { int a; } s;
    //                 ^
    int b;
};

答案 1 :(得分:1)

答案是否定的。 c ++中有很多黑暗的角落,但这不是他们中的一个:)

类和结构具有继承性。工会没有。

实现你正在尝试的唯一方法是将你的工会重构为结构(我说结构只是因为它们有一个默认的公共范围,所以你不需要公开它们)

如果您尝试在union中放置一个struct,则需要添加新struct的额外范围才能访问其值。

正如AndyG的答案显示的那样:

union TestFails
{
    struct foo: public Base {};
    foo f;
    int b;
};

TestFails fails;
fails.f.a = 42;
std::cout << fails.f.a << std::endl;

如果省略一个名为的变量并创建一个偶尔使用命名空间的未命名范围,那么无法从外部访问数据(首先就是这一点)

答案 2 :(得分:0)

不确定是否有帮助,但这有效:

struct Base { int a; };
struct Foo : Base { int b;};
union TestFailsNot {
    Base base;
    Foo foo;
    int b;
};

int main() {
    TestFailsNot failsNot;
    failsNot.foo.a = 0;    
    failsNot.base.a = 3; // maybe not what you want to do, but it works
}