инициализация виртуальных базовых классов

Я работаю над тестом, и мне трудно понять это:

#include <iostream>

struct Car
{
Car() : price(20000) {}
Car(double b) : price(b*1.1) {}
double price;
};
struct Toyota : public virtual Car
{
Toyota(double b) : Car(b) {}
};

struct Prius : public Toyota
{
Prius(double b) : Toyota(b)  {}
};

int main(int argc, char** argv)
{
Prius p(30000);

std::cout << p.price << std::endl;

return 0;
}

Возвращаемое значение составляет 20 000, но на самом деле я не понимаю, почему:

Все подобъекты, представляющие виртуальные базовые классы, инициализируются конструктором самого производного класса. Если конструктор самого производного класса не указывает инициализатор mem для виртуального базового класса V, то вызывается конструктор V по умолчанию для инициализации подобъекта виртуального базового класса.

И я попробовал другой способ создать конструктор в производном классе, но я получил ошибки от компилятора.

Кто-нибудь дает объяснение и как создать такой конструктор?

1

Решение

Удалить виртуальное наследство:

struct Car
{
Car() : price(20000) {}
Car(double b) : price(b*1.1) {}
double price;
virtual ~Car() = default;
};

struct Toyota : public Car
{
Toyota(double b) : Car(b) {}
};

Live Run

Toyota Это Car и не нуждается в виртуальном наследовании.

Читать Вот о виртуальном наследовании, если ваш тест о виртуальном наследовании

0

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

Просто добавьте mem-инициализатор для (косвенной) базы viirtual:

Prius(double b) : Car(b), Toyota(b)  {}

Видеть это жить на колиру.

Виртуальное наследование гарантирует, что виртуальная база будет существовать только один раз в полном объекте. Для этого это не могу быть задачей некоторой промежуточной базы, которая, возможно, даже не единственная, кто ее запрашивает, инициализировать виртуальную базу: какая из них должна получить разрешение?
Вместо этого ctor делится на две части: одна для инициализации всего, кроме виртуальных баз, будь они прямыми или косвенными, и которая используется производными классами, и одна, сначала инициализирующая виртуальные базы, а затем делегирующая остальную часть первой, которая тот призвал создать полный объект.

Большинство компиляторов предупреждают, если вы неправильно указали порядок инициализации mem, поэтому позже вы не удивитесь тому, что на самом деле делает ваш код. Вероятно, это была ошибка, указанная вашим компилятором …

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector