考虑下面的代码:
#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";}
然后我得到这个错误:
错误:'class A A::A' is inaccessible within this context
如何解决问题。我想要的复制构造函数A
, B
and C
当复制构造函数时D
被叫。这可能是很小的变化,但我没有得到。
首先,让我们更改您的继承,因为目前它是私有的:
class B : virtual protected A {...};
class C : virtual protected A {...};
现在,在您的复制构造函数中,显式指定以下复制构造函数A
and B
and C
应该被称为:
class D : protected B, protected C {
D(const D & obj) : A(obj), B(obj), C(obj) {cout << "8";}
};
输出将如期望的那样(2468
).
Why?
当我们有虚拟基类时,必须对其进行初始化由最派生的类,否则就会产生歧义B
or C
例如负责建设A
.
§12.6.2、(13.1):
在非委托构造函数中,初始化按以下顺序进行:
- 首先,且仅适用于最底层派生类 (1.8) 的构造函数,
虚拟基类按照它们出现的顺序进行初始化
有向无环图的深度优先从左到右遍历
基类,其中“从左到右”是出现的顺序
派生类基说明符列表中的基类。
特别是,如果您定义了一个复制构造函数,并省略了它应该调用的复制构造函数的列表,那么默认构造函数将会被使用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)