是否有一种(实用的)方法可以绕过正常(虚拟)构造函数调用顺序?
例子:
class A
{
const int i;
public:
A()
: i(0)
{ cout << "calling A()" << endl; }
A(int p)
: i(p)
{ cout << "calling A(int)" << endl; }
};
class B
: public virtual A
{
public:
B(int i)
: A(i)
{ cout << "calling B(int)" << endl; }
};
class C
: public B
{
public:
C(int i)
: A(i), B(i)
{ cout << "calling C(int)" << endl; }
};
class D
: public C
{
public:
D(int i)
: /*A(i), */ C(i)
{ cout << "calling D(int)" << endl; }
};
int main()
{
D d(42);
return 0;
}
输出:
调用 A()
调用 B(int)
调用 C(int)
调用 D(int)
我想要的是这样的:
调用 A(int)
调用 B(int)
调用 C(int)
调用 D(int)
如您所见,其中涉及到虚拟继承,这导致D的构造函数首先调用A的构造函数,但是由于没有提供参数,所以它调用了A()。有需要初始化的const int i ,所以我遇到了问题。
我想做的是隐藏 C 的继承细节,这就是为什么我正在寻找一种方法来避免在 D(以及每个派生的)构造函数的初始化列表中调用 A(i)。[编辑] 在这种特定情况下,我可以假设只有 C 的非虚拟单继承子类(因为 D 是一个)。[/编辑]
[编辑]
虚拟基类在初始化任何非虚拟基类之前进行初始化,因此只有最派生的类才能初始化虚拟基类。——詹姆斯·麦克内利斯
这正是重点,我不希望最派生类调用虚拟基类构造函数。 [/编辑]
考虑以下情况(上面的代码示例中没有表示):
A
/ \
B0 B1
\ /
C
|
D
我明白为什么在实例化 C 时 C 必须调用 A 的 ctor(歧义),但为什么 D 在实例化 D 时必须调用它?