1、构造函数和析构函数的执行顺序
创建对象时,首先调用基类的构造函数,再调用子类的构造函数。这个过程和修房子装修很像,首先我们要把房子修起来(对应调用基类的构造函数),房子修起来后,我们再对其进行装修(对应调用子类的构造函数)。但是反过来就行不通了。
清除对象时,首先调用派生类的析构函数,再调用基类的析构函数。这个过程和拆房子很像,首先我们要把房子内部的家具等搬走(对应调用子类的析构函数),然后再把房子拆掉(对应调用基类的析构函数)。
#include<iostream>
using namespace std;
class Base{
public:
Base() { cout << "Here is constructor of class Base" << endl; }
~Base() { cout << "Here is destructor of class Base!" << endl; }
};
class Derive : public Base{
public:
Derive() { cout << "Here is constructor of class Derive" << endl; }
~Derive() { cout << "Here is destructor of class Derive!" << endl; }
};
int main(){
Derive *pb = new Derive;
delete pb;
return 0;
}
2、虚析构函数
虚析构函数在使用多态时十分重要。作为基类的构造函数必须为虚函数,否则在使用多态时会出错。
看下面一个例子,基类析构函数不是虚函数:
#include<iostream>
using namespace std;
class Base{
public:
Base() { cout << "Here is constructor of class Base" << endl; }
~Base() { cout << "Here is destructor of class Base!" << endl; }
};
class Derive : public Base{
public:
Derive()
{
cout << "Here is constructor of class Derive" << endl;
}
~Derive()
{
cout << "Here is destructor of class Derive!" << endl;
}
};
int main(){
Base *pb = new Derive;//注意这里
delete pb;
return 0;
}
从输出结果我们可以看出,因为Base类的析构函数不是虚函数,所以只调用了基类的析构函数。而pb实际上是指向一个Derive对象,其析构函数没有得到调用,可能导致某些内存没有得到回收。
看下面一个例子,基类析构函数是虚函数:
#include<iostream>
#include<string>
using namespace std;
class Base{
public:
Base() { cout << "Here is constructor of class Base" << endl; }
virtual ~Base() { cout << "Here is destructor of class Base!" << endl; }
};
class Derive : public Base{
public:
Derive()
{
cout << "Here is constructor of class Derive" << endl;
}
~Derive()
{
cout << "Here is destructor of class Derive!" << endl;
}
};
int main(){
Base *pb = new Derive;
delete pb;
return 0;
}
总结:如果一个类要作为基类,那么把它的析构函数定义为虚函数。