你以为你懂了,考试的时候才发现你不懂,人世间最大的悲剧莫过于此。。。现在数电和工数考完了,浪也浪完了,老老实实把问题搞清楚吧
我们知道,在实例化对象时会调用相应的构造函数,一般情况下按照代码顺序构造,以相反的顺序析构,但情况稍微复杂点时,这个顺序就没那么清楚了。简单的写个小程序,构造几个对象,来看看构造函数的调用顺序,心急的可以直接拖到最下方看结论
class parentMember
{
public:
parentMember()
{
cout << "调用基类成员构造函数" << endl;
}
~parentMember()
{
cout << "调用基类成员析构函数" << endl;
}
};
class parent
{
public:
parent()
{
cout << "调用基类构造函数" << endl;
}
parentMember member1;
~parent()
{
cout << "调用基类析构函数" << endl;
}
};
class childMember
{
public:
childMember()
{
cout << "调用派生类成员构造函数" << endl;
}
~childMember()
{
cout << "调用派生类成员析构函数" << endl;
}
};
class child : parent
{
public:
child(): parent()
{
cout << "调用派生类构造函数" << endl;
cout << "**********************************" << endl;
}
childMember member2;
~child()
{
cout << "调用派生类析构函数" << endl;
}
};
我们让基类和派生类各自包含一个成员对象来让情况复杂一点,在主函数中,我们只需要简单的将派生类实例化即可
int main()
{
child();
return 0;
}
来看运行结果
调用基类成员构造函数
调用基类构造函数
调用派生类成员构造函数
调用派生类构造函数
**********************************
调用派生类析构函数
调用派生类成员析构函数
调用基类析构函数
调用基类成员析构函数
Process returned 0 (0x0) execution time : 0.094 s
Press any key to continue.
结果比较明显了
1.类成员中包含其他对象时,先调用成员对象的构造函数,再调用类自身的构造函数
2.实例化派生类时,先调用基类构造函数,再调用派生类构造函数
3.析构函数调用顺序与构造函数相反
多层基层时,上述顺序应当向上回滚,简单说就是上述输出保持不变,再下面输出第三层派生类的信息,为了验证是否如此,我们稍稍修改一下,顺便看一下static对象的何时构造
再构造一个child的派生类,同样包含有一个成员对象
class member
{
public:
member()
{
cout<<"调用第三层派生类成员构造函数"<<endl;
}
~member()
{
cout<<"调用第三层派生类成员析构函数"<<endl;
}
};
class grandchild : child
{
public:
grandchild()
{
cout << "调用第三层派生类构造函数" << endl;
cout << "**********************************" << endl;
}
member member3;
~grandchild()
{
cout << "调用第三层派生类析构函数" << endl;
}
};
在主函数中,只需要实例化第三层派生类
int main()
{
grandchild();
return 0;
}
来看运行结果
调用基类成员构造函数
调用基类构造函数
调用派生类成员构造函数
调用派生类构造函数
调用第三层派生类成员构造函数
调用第三层派生类构造函数
**********************************
调用第三层派生类析构函数
调用第三层派生类成员析构函数
调用派生类析构函数
调用派生类成员析构函数
调用基类析构函数
调用基类成员析构函数
Process returned 0 (0x0) execution time : 0.279 s
Press any key to continue.
符合之前我们的推断
为了方便看 结论在最后再写一遍
1.类成员中包含其他对象时,先调用成员对象的构造函数,再调用类自身的构造函数
2.实例化派生类时,先调用基类构造函数,再调用派生类构造函数
3.析构函数调用顺序与构造函数相反
4.多层基层时,上述顺序应当向上回滚