当我试图以通常的方式“解决”通常的钻石问题时发生了奇怪的问题 - 使用虚拟继承:
A
/ \* both virtual
B C
\ /
D
但是我的基类A没有默认构造函数,所以我是从D手动调用它。但是当我尝试将C类添加到此钻石作为C继承时
A
/ \* both virtual
B C
\ / \
D E
仍然需要手动调用E构造函数中的A的构造函数,即即使既没有多重继承也没有钻石A-C-E,C不会从E创建A。
class A
{public:
A (int _N): N(_N) {};
void show()
{cout<<"A"<<N;}
protected:
int N;
};
class B: public virtual A
{ public:
B(int n): A(2*n) {};
void show()
{ cout<<"B"<<N;}
};
class C: public virtual A
{ public:
C(int n): A(3*n) {};
void show()
{ cout<<"C"<<N;}
};
class D: public B,C
{ public:
D(): B(1), C(2), A(3) {};
void show()
{ cout<<"D"<<N;}
};
class E: public virtual C
{ public:
E(): C(1) {};
void show()
{ cout<<"E"<<N;}
};
int main()
{D d; // OK
A *a = &d;
a->show();
E e; // NOT OK, no function A::A() to call in E::E()
A *a2 = &e;
a2->show();
return 0;
}
是否可以在不调用E的构造函数的情况下解决此问题?我需要C才能正确地做到这一点:-)。
或者根本不可能尝试解决钻石问题:
A A
| | no virtual at all
B C
\ / \
D E
仍然尝试使用两个A实例来声明D类的对象但是告诉编译器每次从D进行coling时使用A的C?当我尝试添加
时using C::A
进入D的声明它仍然产生明确的基础A的错误。
答案 0 :(得分:3)
是否可以在不调用E的构造函数的情况下解决此问题?我需要C才能正确地做到: - )。
派生程度最高的类(在本例中为E
)的构造函数负责调用任何虚拟基类的构造函数。
C
的构造函数无法调用A
的构造函数,因为C
不是派生类最多的类。虚拟基类在之前初始化任何直接基类,因此E
必须在A
初始化之前初始化C
。
答案 1 :(得分:3)
是的,虚拟基类构造函数调用与虚函数重写不同:
这意味着: