滚动浏览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是该问题的链接
答案 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?