繁体   English   中英

从多重/钻石继承继承

[英]Inheriting from multiple/diamond Inheritance

我有以下情况:

class A
{
  public:
    A(std::string id);
};

class B : public virtual A
{
  public:
    B();
};

class C : public virtual A
{
  public:
    C();
};

class D : public B, public C
{
  public:
    D(std::string id);
};


D::D(std::string id) : A(id), B(), C()
{
}


class X : public D
{
  public:
    X(std::string id);
}

X::X(std::string id) : D(id)
{
}

现在,如果我创建D的实例,则一切正常。 但是,如果我创建X的实例,则会得到一个编译器错误,该错误告诉我某事试图调用A的默认构造函数-该不存在。 如果我创建它,它将编译,但仅调用默认构造函数,因此,未正确设置/初始化id。

可以通过实现X的构造函数来解决此问题,如下所示:

X::X(std::string id) : A(id), D(id)
{
}

但是我的理解是,这应该是不必要的。 那我的错误在哪里?

您需要public所有构造函数,并为A定义一个默认构造函数,因为字符串构造函数会将默认构造函数标记为=delete 此外,引用标准草案初稿最派生的类将初始化任何虚拟基类

12.6.2初始化基础和成员[class.base.init]

10在非委托的构造函数中,初始化按以下顺序进行:—首先,仅对于派生程度最大的类(1.8)的构造函数,虚拟基类将按照它们出现在深度从左至左的顺序进行初始化基类的有向无环图的向右遍历,其中“从左到右”是基类在派生类base-species-list中的出现顺序。

在这种情况下,这意味着X实际上必须A初始化。

#include <iostream>
#include <string>

class A
{
public:
  A() { std::cout << "A\n"; }
  A(std::string id) { std::cout << id << " A(id)\n"; }
};

class B : public virtual A
{
public:
   B() { std::cout << "B\n"; }
};

class C : public virtual A
{
public:
   C() { std::cout << "C\n"; }
};

class D : public B, public C
{
public:  
   D(std::string id): A(id) { std::cout << id << " D(id)\n"; }
};


class X : public D
{
public:
  X(std::string id): A(id), D(id) { std::cout << id << " X(id)\n"; }
};

int main()
{
   X x("bla");
   x;       
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM