【问题标题】:C++ primer 5th ed. Virtual inheritance and ctor-initC++ 入门第 5 版。虚拟继承和ctor-init
【发布时间】:2021-07-14 04:03:16
【问题描述】:

C++ 入门第 5 版。第18章多重和虚继承,我有一个问题:

练习 18.30:在 Base 中定义一个默认构造函数、一个复制构造函数和一个具有 int 参数的构造函数。在每个派生类中定义相同的三个构造函数。每个构造函数都应该使用它的参数来初始化它的 Base 部分。

我试图用这种方式解决它,所以这是我的继承层次结构:

struct Class {
    Class(){cout << "Class()\n";}
    ~Class(){cout << "~Class()\n";}
};

struct Base : Class {
    Base(){cout << "Base()\n";}
    Base(int){cout << "Base(int)\n";}
    Base(Base const&){cout << "Base(Base const&)\n";}

    ~Base(){cout << "~Base()\n";}
};

struct D1 : virtual public Base {
    D1(){cout << "D1()\n";}
    D1(int x) : Base(x){
        cout << "D1(int)\n";
    }
    D1(D1 const& rhs) : Base(rhs){
        cout << "D1(D1 const&)\n";
    }

    ~D1(){cout << "~D1()\n";}
};

struct D2 : virtual public Base {
    D2(){cout << "D2()\n";}
    D2(int x) : Base(x){
        cout << "D2(int)\n";
    }
    D2(D2 const& rhs) : Base(rhs){
        cout << "D2(D2 const&)\n";
    }
    ~D2(){cout << "~D2()\n";}
};

struct MI : public D1, public D2 {
    MI(){cout << "MI()\n";}
    MI(int x) : Base(x), D1(x), D2(x){
        cout << "MI(int)\n";
    }
    MI(MI const& rhs) : Base(rhs), D1(rhs), D2(rhs){
        cout << "MI(MI const&)\n";
    }

    ~MI(){cout << "~MI()\n";}
};

struct Final : public MI, public Class {
    Final(){cout << "Final()\n";}
    Final(int x) : MI(x){
        cout << "Final(int)\n";
    }
    Final(Final const& rhs) : MI(rhs), Class(rhs){
        cout << "Final(Final const&)\n";
    }

    ~Final(){cout << "~Final()\n";}
};

现在如果我编译程序我会得到错误:

 error: ‘Class’ is an ambiguous base of ‘Final’

所以问题出在Final 类的复制构造函数初始化列表中,那么我该如何在复制构造函数中初始化Class 的子部分。

  • Final(int) 没有抱怨,因为我让 Class() 的默认 ctor 运行:

      Final(int x) : MI(x) // Class default ctor is executed.
    

所以请帮助我解决这个问题。谢谢!

【问题讨论】:

  • 我面前没有那本书,但我猜你误解了你的描述中没有包含的部分 excersize(例如,确切地说, “每个派生类”的意思)。否则,根据显示的代码,本书要求您实现一个疯狂的类层次结构。我不希望有一本有声望的书来宣传。
  • @SamVarshavchik:我只实现了要求的构造函数并复制并粘贴了练习。
  • @SamVarshavchik:这是因为Base 是一个虚拟基类,因此必须由最派生的类初始化,因此它必须看起来像:Final(Final const&amp; rhs) : Base(rhs), MI(rhs){ cout &lt;&lt; "Final(Final const&amp;)\n"; } 现在可以正常工作了吗?!
  • 我不明白struct Final : public MI, public Class 的原因。 struct Final -&gt; struct MI -&gt; struct D1 -&gt; struct Base -&gt; struct Class 继承链已经存在,那么写public Class 的意义何在。删除它。
  • 请假装你是一个完全陌生的人,你什么都不知道,没有这本书,也读过你上面引用的excersize的描述。只有那三句话,没有别的。这就是你,一个完全陌生的人所知道的一切。现在,你能回答下面的问题吗:你有什么想法,有什么想法,在“复制和粘贴 excersize”的描述中,“每个派生类”是什么意思?

标签: c++ constructor initialization multiple-inheritance virtual-inheritance


【解决方案1】:

这是 inaccessible-base 类的情况。 Final 类已经有一个继承链:

struct Final -> struct MI -> struct D1 -> struct Base -> struct Class

写成class Square: public Shape 表示is-a 关系,所以Square is-a 形状。对于您的类链,它还在FinalClass 之间建立了相同的关系,尽管通过许多中间父系谱系。在struct Final : public MI, public Class 中写public Class 实际上是多余的。在现实世界的类比中,这类似于表明曾曾祖父是直系父亲,除非我们在讨论幻想或反常的东西,否则这是不适用的。编译器在警告中声明了here,显示了它所提出的歧义,然后无法编译代码。这个here 有一个更细微的答案。对于您的具体问题,只需从Final 中删除Class 就应该是fine 进行编译。

附:请考虑将 Class 重命名为其他名称,因为这是 C++ 并且...class 是一件大事。 class Class 将非常难以阅读。

【讨论】:

    猜你喜欢
    • 2021-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-08
    • 2016-03-26
    • 2011-01-08
    相关资源
    最近更新 更多