虚基类和继承

时间:2017-04-05 06:24:25

标签: c++

滚动浏览SO时,我发现了这个问题

#include <iostream>

using namespace std;

class base
{
   public:
      base()
      {
         cout << "ctor in base class\n";
      }
};

class derived1 : public base
{
   public:
      derived1()
      {
         cout <<"ctor in derived class\n";
      }
};

int main()
{
   derived1 d1obj;
   return 0;
}

有这样的问题: - 当创建d1obj时,控件首先到达基类构造函数,然后它转到派生类构造函数?或者它是相反的方式:它首先到达派生类构造函数,发现它有基类,所以控件转到基类的构造函数?

并且aswer包含部分

当一个类具有虚拟基础时,构造函数通常会发出两个不同的函数体 - 一个用于此类是派生类型最多的一个,另一个用于使用当这个类本身就是一个基类时。原因是虚拟基类是由派生程度最高的类构建的,以确保在它们共享时它们只构造一次。因此构造函数的第一个版本将调用所有基类构造函数,而第二个版本将仅调用非虚拟基础构造函数。

有人可以用一个例子向我解释这个吗?

Here是该问题的链接

2 个答案:

答案 0 :(得分:1)

在您的示例中,它是derived1的默认构造函数,负责调用base的默认构造函数。但是,仅当derived1是实际(派生的)对象时才需要这样做,如示例中所示

int main()
{
  derived1 d1obj; // Most derived object of type `derived1`
  // It contains a direct `base` subobject
  // Constructor of `derived1` must construct `base` subobject as well
} 

但是当derived1使用较大对象的基础子对象时

class derived2 : public derived1
{
public:
  derived2()
  {
     cout <<"ctor in derived 2 class\n";
  }    
};

int main()
{
  derived2 d2obj; // Most derived object of type `derived2`
  // It contains a direct `derived1` subobject and an indirect `base` subobject 
  // (through `derived1`)
  // Constructor of `derived2` must directly construct both `derived1` subobject and 
  // `base` subobject 
  // Which means that constructor of `derived1` subobject should not attempt
  // to construct `base` subobject
}

然后它是derived2的构造函数,负责调用derived1的默认构造函数和默认构造函数base。在这种情况下,derived1的默认构造函数将调用base的构造函数,因为它将导致base的双重构造。

为了满足所有这些要求,derived1通常会有两个版本的默认构造函数:原始示例中调用的完整版本和上面示例中从derived2调用的“简化”版本。

或者,derived1的默认构造函数可以使用隐藏的布尔参数实现,该参数将告诉它是否调用base的默认构造函数。

答案 1 :(得分:0)

&#34;当一个类具有虚拟基础时,构造函数通常会发出两个不同的函数体 - 一个用于此类是派生类型最多的一个,另一个用于此时class本身就是一个基类。原因是虚拟基类是由派生程度最高的类构建的,以确保在它们共享时它们只构造一次。因此构造函数的第一个版本将调用所有基类构造函数,而第二个版本将仅调用非虚拟基础的构造函数。&#34;

在这个问题中,回答者实际上想要说一下在多重继承中被称为可怕钻石的C ++中常见的情况。 了解只是看到这个链接最受欢迎的答案 In C++, what is a virtual base class?