有没有(实际可行的)方法来绕过正常的(虚拟)构造函数调用顺序?
示例:
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)[/编辑]
[编辑]
虚基类在任何非虚基类之前初始化,因此只有最派生类才能初始化虚基类。 - James McNellis
这正是重点,我不想让最派生类调用虚基类构造函数。 [/编辑]
考虑以下情况(在上面的代码示例中未表示):
A
/ \
B0 B1
\ /
C
|
D
我理解为什么在实例化C时,C必须调用A的构造函数(模棱两可性),但是在实例化D时为什么也要调用它呢?