虚拟基类初始化

时间:2018-08-31 09:36:42

标签: c++ c++11 constructor virtual-inheritance ctor-initializer

我正在测试,我很难理解这一点:

#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;
}

返回值为20000,但实际上我不明白为什么:

  

表示虚拟基类的所有子对象都由最派生类的构造函数初始化。如果最派生类的构造函数未为虚拟基类V指定mem初始化器,则将调用V的默认构造函数以初始化虚拟基类子对象。

我尝试了其他方法在派生类中创建构造函数,但从编译器中收到错误。

有人提供解释以及如何创建此类构造函数吗?

2 个答案:

答案 0 :(得分:0)

只需为(间接)虚拟基础添加mem-initializer:

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

live on coliru看到它。

虚拟继承确保虚拟库在完整对象中仅存在一次。为此, 不能成为某个中间基础的任务,甚至可能不是唯一一个要求它初始化虚拟基础的任务:哪个基础应该获得批准?
而是将ctor分为两部分:一个用于初始化除虚拟基础之外的所有内容,无论它们是直接还是间接的,并由派生类使用,一个首先初始化虚拟基础,然后将其余部分委托给前者,即一个要求创建一个完整的对象。

如果错误地调用了mem-initializers,大多数编译器都会发出警告,因此以后您对代码的实际作用并不感到惊讶。那可能是编译器指出的错误...

答案 1 :(得分:0)

删除虚拟继承:

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,不需要虚拟继承。

如果您的测试涉及虚拟继承,请阅读here关于虚拟继承的信息