2010-08-19 94 views
16

可能有类的虚拟继承不提供默认构造函数?默认的构造函数和虚拟继承

目前的菱形图(最简单的一个,没有提供默认的构造函数)没有编译(g ++ 4.4.3)。

class A { 
public: 
    A(int) {} 
}; 
class B : virtual public A { 
public: 
    B(int i) : A(i) {} 
}; 
class C : virtual public A { 
public: 
    C(int i) : A(i) {} 
}; 
class D : public B, public C { 
public: 
    D(int i) : B(i), C(i) {} 
}; 

感谢, 弗朗切斯科

回答

3

我相信你D类还需要显式调用A的在它的初始化列表构造。

22

你需要调用A的构造这里明确

D(int i) : A(i), B(i), C(i) {} 

虚基类的特别之处在于它们是由最派生类而不是从虚拟继承任何中间基类初始化基础。哪个潜在的多个初始化器可以正确选择初始化一个基地址?

如果最派生类被构造在其成员列表initalization则虚拟基类与必须存在且可访问其默认的构造初始化没有列出它。

无耻地从here复制:-)

1

的多布斯医生文章Multiple Inheritance Considered Useful解释处理这个问题的各种方法。这个建议基本上是提供默认的构造函数和方法。它增加了更多的工作,为B和C,但防止d自不必了解A.

+1

离开d不知道A的,当然,理想的。在“的init()”的解决方案,不幸的是,有一个缺点:A的构造将被调用两次(一次由每个B和C)可具有副作用(特别是如果使用静态成员)。另外,如果开发人员创建'class D:public A {}',则可能根本不会调用'init()'方法,使对象保持未初始化状态。 – Marste 2015-08-12 13:05:59

0

你需要显式调用的结构是这样的:

D(int i) : A(i), B(i), C(i) {}