如何在C ++中调用所有基类的复制构造函数,以在钻石继承中复制大多数派生类对象? [英] How to call copy constructor of all base classes for copying most derived class object in diamond inheritance in C++?
问题描述
考虑以下代码:
#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
类的副本构造函数.在继承期间,我们需要显式调用基类的副本构造函数,否则仅调用基类的默认构造函数.我一直了解到这里.
So, for line D d(d1)
the copy constructor of D
class is bein called. During inheritance we need to explicitly call copy constructor of base class otherwise only default constructor of base class is called. I understood till here.
我的问题:
现在,我要在D d(d1)
执行期间调用所有基类的副本构造函数.为此,如果我尝试下面
D(const D & obj) : A(obj), B(obj), C(obj) {cout << "8";}
然后我得到这个错误:
错误:'class A A::A' is inaccessible within this context
Now I want to call copy constructor of all base classes during D d(d1)
execution. For that if I try below
D(const D & obj) : A(obj), B(obj), C(obj) {cout << "8";}
Then I get this error:
error: 'class A A::A' is inaccessible within this context
如何解决此问题.当调用D
的副本构造函数时,我想要A
,B
和C
的副本构造函数.这可能是很小的变化,但我没有得到.
How to resolve the issue. I want copy constructor of A
, B
and C
when copy constructor of D
gets called. It might be very small change but I am not getting.
推荐答案
首先,让我们更改继承,因为目前它是私有的:
First, lets change your inheritance as currently it is private:
class B : virtual protected A {...};
class C : virtual protected A {...};
现在,在您的副本构造函数中,明确指定应调用A
和B
和C
的副本构造函数:
Now, in your copy constructor, explicitly specify that the copy constructors of A
and B
and C
should be called:
class D : protected B, protected C {
D(const D & obj) : A(obj), B(obj), C(obj) {cout << "8";}
};
并且输出将是所需的(2468
).
And the output will be as desired (2468
).
当我们有虚拟基类时,必须由最派生的类对其进行初始化,否则对于B
或C
是造成A
.
When we have virtual base classes, they must be initialized by the most derived class, otherwise there would be ambiguity concerning whether B
or C
for example is responsible for the construction of A
.
§12.6.2,(13.1):
§12.6.2, (13.1):
在非委托构造函数中,初始化按以下顺序进行:
In a non-delegating constructor, initialization proceeds in the following order:
- 首先,并且仅适用于派生程度最高的类(1.8)的构造函数, 虚拟基类按照它们在窗口中出现的顺序进行初始化 的有向无环图的深度优先从左到右遍历 基本类,其中从左到右"是 派生类base-specifier-list中的基本类.
- 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.
特别是,如果您定义了一个复制构造函数,并省略了它应该调用的复制构造函数列表,那么将使用默认构造函数.
In particular, if you define a copy constructor, and omit the list of copy constructors it should call, then the default constructors will be used.
这篇关于如何在C ++中调用所有基类的复制构造函数,以在钻石继承中复制大多数派生类对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!