基类和派生类:构造函数和析构函数的执行顺序
在Visual Studio中,新建控制台工程,构造类如下:
#include<iostream>
using namespace std;
class CBase {
public:
CBase() {
cout << "CBase():Constructor" << endl;
}
~CBase() {
cout << "CBase(): Destructor" << endl;
}
};
class CDerive :public CBase {
public:
CDerive() {
cout << "CDerive():Constructor" << endl;
}
~CDerive() {
cout << "CDerive(): Destructor" << endl;
}
};
对应不同的指针进行 delete 操作,结果如下:
(i)
int main(int argc, char* argv[])
{
CBase* p = new CDerive();
delete p;
return 0;
}
运行结果:
S:\ComputerTech\VS2015\Release>Test.exe
CBase():Constructor
CDerive():Constructor
CBase(): Destructor
(ii)
int main(int argc, char* argv[])
{
CDerive* pp = new CDerive();
delete pp;
return 0;
}
运行结果:
S:\ComputerTech\VS2015\Release>Test.exe
CBase():Constructor
CDerive():Constructor
CDerive(): Destructor
CBase(): Destructor
(iii)
int main(int argc, char* argv[])
{
CDerive* pp = new CDerive();
CBase * p = (CBase*)pp;
delete p;
return 0;
}
运行结果:
S:\ComputerTech\VS2015\Release>Test.exe
CBase():Constructor
CDerive():Constructor
CBase(): Destructor
(iv)
int main(int argc, char* argv[])
{
CBase * p = new CDerive();
CDerive * pp = (CDerive*)p;
delete pp;
return 0;
}
运行结果:
S:\ComputerTech\VS2015\Release>Test.exe
CBase():Constructor
CDerive():Constructor
CDerive(): Destructor
CBase(): Destructor
总结:
由上面的实验结果可以看出,当 new CDerive() 时,会先运行基类的构造函数,然后再运行派生类的构造函数;
而当 delete pointer 时,编译器只考虑 pointer 指针本身的类型而不关心 pointer 实际指向的类型,即:若 pointer 为基类指针,则只调用基类的析构函数(不管 pointer 实际指向的是基类还是派生类);若 pointer 是派生类指针,则先调用派生类的析构函数,再调用基类的析构函数,调用顺序与调用构造函数的顺序相反。