我有这个C ++代码:
class BaseClass {
int id;
public:
BaseClass() { printf("BaseClass()\n"); }
virtual ~BaseClass() { printf("~BaseClass()\n"); }
};
class Class1 : public BaseClass
{
int id;
public:
Class1() { printf("Class1()\n"); }
~Class1() { printf("~Class1()\n"); }
};
class Class2 : public Class1
{
BaseClass id;
public:
Class2() { printf("Class2()\n"); }
~Class2() { printf("~Class2()\n"); }
};
class Class3 : virtual public BaseClass
{
int id;
public:
Class3() { printf("Class3()\n"); }
~Class3() { printf("~Class3()\n"); }
};
class Class4 : public Class3, virtual public Class1
{
Class3 id;
public:
Class4() { printf("Class4()\n"); }
~Class4() { printf("~Class4()\n"); }
};
int main(int argc, char* argv[])
{
BaseClass *p = new Class2;
Class2 *p1 = new Class2;
Class3 *p2 = new Class3;
delete p;
delete p1;
delete p2;
return 0;
}
这是输出:
BaseClass()
Class1()
BaseClass()
Class2()
BaseClass()
Class1()
BaseClass()
Class2()
BaseClass()
Class3()
~Class2()
~BaseClass()
~Class1()
~BaseClass()
~Class2()
~BaseClass()
~Class1()
~BaseClass()
~Class3()
~BaseClass()
我不明白为什么。我希望输出如下:
BaseClass()
Class1()
Class2()
BaseClass()
Class1()
Class2()
...
等
为什么Class2()
在创建Class1()
之后没有打印p1
,例如{{1}}?
这与虚拟继承有关吗?
答案 0 :(得分:3)
为什么在创建例如p1时,在Class1()之后打印Class2()?
由于Class2
具有类型为BaseClass
的非静态成员对象,因此将在Class2
的ctor之前调用其ctor。
初始化顺序
1)如果构造函数是针对派生程度最高的类的虚拟基础 类按它们出现的顺序初始化 基类深度优先从左到右遍历基类声明 (从左到右指的是基本说明符列表中的外观)
2)然后,直接基类按从左到右的顺序初始化为 它们出现在这个类的基本说明符列表中
3)然后,按照以下顺序初始化非静态数据成员 类定义中的声明。
4)最后,执行构造函数的主体
对于new Class2;
,将首先调用直接基类Class1
及其基类BaseClass
。然后将调用类型为id
的非静态数据成员BaseClass
。最后将调用Class2
的ctor的主体。所以你会得到
BaseClass()
Class1()
BaseClass()
Class2()
答案 1 :(得分:2)
让我们一步一步地构建第一个对象:
p
这是你要构建的第一个对象,我们称之为BaseClass()
。
p
BaseClass
的{{1}}。
Class1()
p
的{{1}},Class1
的子类被构建。
BaseClass
这是BaseClass()
正在构建的id
成员。
Class2
现在,最后,Class2()
,Class2
本身。
所以,尽管你不相信,p
是在Class2()
之后打印的。除非您忘记Class1()
也有Class2
成员,这是id
,并且必须在调用BaseClass
构造函数之前构建它。您认为您正在构建第二个Class2::Class2()
ed对象的new
,但实际构建的是BaseClass
成员对象。
P.S。这是BaseClass
。在C++
中,我们使用C++
代替std::cout
()。 printf
是......上个世纪。