Я думаю, что пример будет описывать мою проблему лучше.Определение конструктора с виртуальным множественным наследованием
struct Base {
Base() = delete;
Base(int x) : x(x) {}
int x;
};
struct Derived1 : virtual Base {
Derived1(int y) : Base(5), y(y) {}
int y;
};
struct Derived2 : virtual Base {
Derived2(int z) : Base(10), z(z) {}
int z;
};
struct Derived3: Derived1, Derived2 {
public:
Derived3(int y, int z) : Derived1(y), Derived2(z) {}
};
И ошибка я получаю: In constructor ‘Derived3::Derived3(int, int)’: error: use of deleted function ‘Base::Base()’ Derived3(int y, int z) : Derived1(y), Derived2(z) {}
Я не понимаю, почему эта ошибка возникает. На мой взгляд, все базовые классы фактически инициализируются в этом примере через их конструкторы (явно Derived1
и Derived2
и неявно Base
- Derived2
(я не уверен здесь, может быть, через Derived1
)). Хорошо, давайте сделаем то, что говорит мне компилятор.
struct Derived3: Derived1, Derived2 {
public:
Derived3(int y, int z) : Base(-1), Derived1(y), Derived2(z) {}
};
Он компилирует и если я сейчас это:
Derived3 d = Derived3(7, 9);
std::cout << d.x << std::endl;
std::cout << d.y << std::endl;
std::cout << d.z << std::endl;
я -1, 7, 9
. И это совсем не то, чего я хотел. Идея состояла в том, чтобы инициализировать базовый класс с одним из его производных классов, и я ожидал, что первый номер быть 5 или 10.
Итак, вот мой вопрос: Почему я вынужден явно вызвать конструктор Base
когда Он уже сделано в одном из производных классов?
Более конкретно, поскольку у меня есть множественное наследование и виртуальное наследование, я считаю, что любой экземпляр Derived3
имеет ровно одну копию экземпляра класса Base
. И я ожидал, что эта копия Base
инициализируется в наиболее производном классе его (Derived1
или Derived2
), но, как я могу ясно видеть, что это не работает таким образом = (Где я ошибаюсь?
Виртуальное наследование сложно. Ключ состоит в том, что виртуальный базовый подобъект «принадлежит» самому производному объекту, который также должен его инициализировать. –
Вы правы в том, что 'Base' инициализируется в самом производном классе, но этот класс является' Derived3'. – molbdnilo
@molbdnilo, тот похоже логичный. Может быть, вы знаете, как я могу сделать один из классов 'Derived1' и' Derived2' самым производным, поэтому мне не нужно будет вызывать 'Base (int)' в 'Derived3'? Я попытался создать более длинную цепочку подклассов, но это не сработало. – antonpp