инициализация виртуальных базовых классов - PullRequest
0 голосов
/ 31 августа 2018

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

#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 по умолчанию для инициализации подобъекта виртуального базового класса.

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

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

Ответы [ 2 ]

0 голосов
/ 31 августа 2018

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

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 Is-a Car и не нуждается в виртуальном наследовании.

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

0 голосов
/ 31 августа 2018

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

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

Посмотри живи на колиру .

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...