与上一篇文章相对应,这一篇文章我们来说下“为什么析构函数中可以为虚函数?”
在派生体系中,我们同长情况下会将顶层基类的析构函数定义为虚函数。这样做的目的是:当我们将派生类指针转换为基类指针时,如果基类中析构函数不是虚函数,当我们删除该指针时不能够释放派生类的资源。例子如下:
(1)
#include<iostream>
using namespace std;
class base
{
public:
base(){ cout << "in base constructor!" << endl; }
virtual void dosomething(){ cout << "do some thing in base!" << endl; }
~base(){ cout << "in base destructor!" << endl; } //基类的析构函数不是虚函数
};
class derived : public base
{
public:
derived(){ cout << "in derived constructor!" << endl; }
void dosomething(){ cout << "do some thing in derived!" << endl; }
~derived(){ cout << "in derived destructor!" << endl; }
};
int main()
{
base *b = new derived();
b->dosomething();
delete b;
return 0;
}
结果:
从结果看出,当我们delete b;后发现只调用了基类的析构函数,没有调用派生类的析构函数,这样在派生类中申请的资源得不到释放会造成资源泄露。
(2)当我们将基类的析构函数定义为虚函数时,
#include<iostream>
using namespace std;
class base
{
public:
base(){ cout << "in base constructor!" << endl; }
virtual void dosomething(){ cout << "do some thing in base!" << endl; }
virtual ~base(){ cout << "in base destructor!" << endl; } //基类的析构函数是虚函数
};
class derived : public base
{
public:
derived(){ cout << "in derived constructor!" << endl; }
void dosomething(){ cout << "do some thing in derived!" << endl; }
~derived(){ cout << "in derived destructor!" << endl; }
};
int main()
{
base *b = new derived();
b->dosomething();
delete b;
return 0;
}
结果显示,这里调用了派生类和基类的析构函数。
注意:因此在以后的编程中,我们最好形成一个习惯将最顶层基类的析构函数定义为虚函数。