如何在C ++中调用所有基类的复制构造函数,以在钻石继承中复制大多数派生类对象? [英] How to call copy constructor of all base classes for copying most derived class object in diamond inheritance in C++?

查看:147
本文介绍了如何在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的副本构造函数时,我想要ABC的副本构造函数.这可能是很小的变化,但我没有得到.

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 {...};

现在,在您的副本构造函数中,明确指定应调用ABC的副本构造函数:

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).

当我们有虚拟基类时,必须由最派生的类对其进行初始化,否则对于BC是造成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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆