虚拟基类和初始化列表

发布于 2024-10-15 02:29:47 字数 1092 浏览 6 评论 0原文

可能的重复:
gcc c++ 虚拟继承问题

大家好,

我想知道编译器将如何处理使用虚拟基类的多重继承时不同的初始化值。考虑一下臭名昭著的“恐惧钻石”继承方案:

     Base
     / \
    /   \
  D1     D2
    \   /
     \ /
     Join

为了避免在 Join 中拥有两个 Base 副本,我对 D1 使用虚拟继承和 D2 (参见此处)。现在,假设 Base 不是抽象的,但有一个成员字段,该字段在其构造函数中初始化:

class Base { 
public:
    Base(int x_) {x = x_;};
    virtual ~Base(){};

public:
    int x;
};

class D1 : public virtual Base {
public:
    D1() : Base(1) {};
    virtual ~D1(){};
};

class D2 : public virtual Base {
public:
    D2() : Base(2) {};
    virtual ~D2(){};
};

class Join : public D1, public D2 {
public:
    Join(){};
    ~Join(){};
};

int main()
{
   Join j;
   cout << j.x << endl;

   return 0;
}

输出是 1、2 还是依赖于编译器?

Possible Duplicate:
gcc c++ virtual inheritance problem

Hi all,

I'm wondering about how the compiler would handle different initialization values when using multiple inheritance from a virtual base class. Consider the notorious 'diamond of dread' inheritance scheme:

     Base
     / \
    /   \
  D1     D2
    \   /
     \ /
     Join

In order to avoid having two copies of Base in Join, I use virtual inheritance for D1 and D2 (see e.g. here). Now, lets say Base is not abstract, but has a member field, which is initialized in its constructor:

class Base { 
public:
    Base(int x_) {x = x_;};
    virtual ~Base(){};

public:
    int x;
};

class D1 : public virtual Base {
public:
    D1() : Base(1) {};
    virtual ~D1(){};
};

class D2 : public virtual Base {
public:
    D2() : Base(2) {};
    virtual ~D2(){};
};

class Join : public D1, public D2 {
public:
    Join(){};
    ~Join(){};
};

int main()
{
   Join j;
   cout << j.x << endl;

   return 0;
}

Will the output be 1, 2, or is it compiler-dependent?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

戏蝶舞 2024-10-22 02:29:47

它不应该编译。虚拟基由最底层的派生类Join 初始化。 Join 不会显式初始化 Base,但 Base 没有可访问的默认构造函数。

[它也不会编译,因为类的定义需要用 ; 终止,但我认为这是一个拼写错误。 main 还应该返回 int 并且我假设 jxj->x 的拼写错误。 ]

It shoudn't compile. Virtual bases are initialized by the most derived class which is Join. Join doesn't explicitly initialize Base but Base has no accessible default constructor.

[It also won't compiler because definitions of classes need to be terminated with a ; but I've assumed that this is a typo. main should also return int and I've assumed that j.x is a typo for j->x.]

旧人哭 2024-10-22 02:29:47

当您具有虚拟继承时,最终类必须初始化虚拟基类。

因此,Join 的构造函数必须构造 Base:

   class Join : public D1, public D2 
    {
    public:
        Join() : Base(3){} // or whatever value
        ~Join(){}
    };

这是类通常只初始化其直接基类这一规则的例外。

(除了 main 应该返回 int 并且您需要执行 j->x 而不是 jx 作为j 是一个指针,并且您必须在调用 new删除它)

When you have virtual inheritance it is the final class that must initialise the virtual base class.

Therefore the constructor of Join must construct Base:

   class Join : public D1, public D2 
    {
    public:
        Join() : Base(3){} // or whatever value
        ~Join(){}
    };

It is the exception to the rule that classes only normally initialise their immediate base-classes.

(Aside from that main should return int and you would need to do j->x not j.x as j is a pointer, as well as the fact you must delete it as you called new)

海之角 2024-10-22 02:29:47

由于 Base 没有隐式构造函数,并且 C1C2 都是虚拟基,因此您必须像这样更改它(并且还在其余的后面添加分号) Charles Bailey 指出的类声明)

class Join : public D1, public D2 {
public:
    Join() : Base(3) {};
    ~Join(){};
};

int main()
{
   Join j;
   cout << j.x << endl;
}

然后它将打印 3 到标准输出

Since the Base does not have an implicit constructor and both C1 and C2 are virtual bases, you would have to change it like this (and also add semicolons after the rest of the class declarations as pointed out by Charles Bailey)

class Join : public D1, public D2 {
public:
    Join() : Base(3) {};
    ~Join(){};
};

int main()
{
   Join j;
   cout << j.x << endl;
}

Then it would print 3 to the standard output

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文