22

问题:

class Base {
public:
  Base(Base* pParent);
  /* implements basic stuff */
};

class A : virtual public Base {
public:
  A(A* pParent) : Base(pParent) {}
  /* ... */
};

class B : virtual public Base {
public:
  B(B* pParent) : Base(pParent) {}
  /* ... */
};

class C : public A, public B {
public:
  C(C* pParent) : A(pParent), B(pParent) {} // - Compilation error here
  /* ... */
};

在给定的位置,gcc 抱怨它无法匹配对 Base() 的函数调用,即默认构造函数。但是C不直接从Base继承,只通过A和B。那么为什么gcc在这里抱怨呢?

想法?TIA /罗伯

4

3 回答 3

46

virtual基类的特殊之处在于它们由最派生类初始化,而不是由继承自虚拟基的任何中间基类初始化。哪个潜在的多个初始化器将是初始化一个基的正确选择?

如果正在构造的最派生类未将其列在其成员初始化列表中,则虚拟基类将使用其默认构造函数进行初始化,该构造函数必须存在且可访问。

请注意,允许在构造函数的初始化程序列表中使用虚拟基标识符,即使它不是所讨论类的直接基。

于 2010-01-24T09:15:54.923 回答
8

您需要从 C 显式调用 Base 的构造函数:

class C : public A, public B {
public:
C(C* pParent) : Base(pParent), A(pParent), B(pParent) {}
/*... */
};
于 2010-01-24T09:17:03.040 回答
5

如果您声明自定义构造函数,则默认构造函数将被禁用。在虚拟继承中,您需要直接调用虚拟继承的构造函数,否则它将不知道是由 A 初始化还是由 B 初始化。

于 2010-01-24T09:06:24.207 回答