Наследование от множественного / алмазного Наследования

У меня есть следующий сценарий:

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 по умолчанию — который не существует. Если я его создаю, он компилируется, но вызывается только конструктор по умолчанию, и, соответственно, идентификатор не установлен / инициализирован неправильно.

Это можно исправить, реализовав конструктор X следующим образом:

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

Но я понимаю, что это не нужно. Так где моя ошибка?

2

Решение

Вам нужно сделать все ваши конструкторы public и определить конструктор по умолчанию для A потому что строковый конструктор пометит конструктор по умолчанию как =delete, Более того, самый производный класс инициализирует любой виртуальный базовый класс, цитата из проект стандарта:

12.6.2 Инициализация баз и членов [class.base.init]

10 В не делегирующем конструкторе инициализация продолжается в
следующий порядок: — сначала и только для конструктора самого
производный класс (1.8), виртуальные базовые классы инициализируются в порядке
они появляются на глубине слева направо обхода направленного
ациклический граф базовых классов, где «слева направо» — это порядок
Появление базовых классов в производном классе
база-специфический эр-лист.

В этом случае это означает, что 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;
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]