考虑以下代码:
#include<iostream> using namespace std; class A { public: A() {cout << "1";} A(const A &obj) {cout << "2";} }; class B: virtual A { public: B() {cout << "3";} B(const B & obj) {cout<< "4";} }; class C: virtual A { public: C() {cout << "5";} C(const C & obj) {cout << "6";} }; class D:B,C { public: D() {cout << "7";} D(const D & obj) {cout << "8";} }; int main() { D d1; cout << "\n"; D d(d1); }
该计划的输出如下:
1357 1358
因此,对于行D d(d1),可以调用D类的复制构造函数.在继承期间,我们需要显式调用基类的复制构造函数,否则只调用基类的默认构造函数.直到这里我明白了.
我的问题:
现在我想在D d(d1)执行期间调用所有基类的复制构造函数.如果我尝试以下,那就是这个
D(const D& obj):A(obj),B(obj),C(obj){cout<< “8”;}
然后我收到这个错误:
错误:’A A A :: A’在此上下文中无法访问
解决方法
首先,让我们改变您的继承,因为它是私有的:
class B : virtual protected A {...}; class C : virtual protected A {...};
现在,在您的复制构造函数中,明确指定应调用A和B和C的复制构造函数:
class D : protected B,protected C { D(const D & obj) : A(obj),C(obj) {cout << "8";} };
输出将符合要求(2468).
为什么?
当我们有虚拟基类时,它们必须由派生程度最高的类初始化,否则就B或C是否负责构造A而言会有歧义.
§12.6.2,(13.1):
In a non-delegating constructor,initialization proceeds in the following order:
- First,and only for the constructor of the most derived class (1.8),
virtual base classes are initialized in the order they appear on a
depth-first left-to-right traversal of the directed acyclic graph of
base classes,where “left-to-right” is the order of appearance of the
base classes in the derived class base-specifier-list.