2012年C++专家进阶之四
问题描述
当一个类打算被用作其它类的基类时,它的析构函数必须是虚的。为什么呢?
背景说明
面向对象编程里面有一个多态的核心概念。C++中的虚函数的主要作用就是用来实现多态机制。
多态,简而言之就是用:基类的指针指向其派生类的实例,然后通过基类的指针调用实际派生类的成员函数,让基类指针所指的成员函数具有“多种表现或者实现形态”。
根本原因
而我们往往又通过基类的指针来销毁对象,但是这个时候如果析构函数不是虚函数,就不能正确识别对象类型从而不能正确调用析构函数。
代码展示
class A
{
public:
A() { ptra_ = new char[10];}
~A() { delete[] ptra_;} // 非虚析构函数
private:
char * ptra_;
};
class B: public A
{
public:
B() { ptrb_ = new char[20];}
~B() { delete[] ptrb_;}
private:
char * ptrb_;
};
void foo()
{
A * a = new B;
delete a;
}
运行效果
在该段代码中,在执行delete a的时候,实际上仅仅只有A::~A()被调用了,而B类的析构函数并没有被调用!
期望效果
正确调用B类的析构函数
造成后果
这是非常可怕的,也是后果很严重的。没有正确及时的释放内存空间,没有释放资源。
改进方法
将A类的析构函数~A()改为virtual虚函数,就可以保证也在delete a的时候B::~B()可以被正确调用。因此基类的析构函数都必须写成虚函数virtual。
结论
基类的析构函数必须写成虚函数。
在编写Code的时候,建议将析构函数定义为虚函数。因为你不知道,也不确定正在使用的类,将来哪一天不会被扩展,将来哪一天不会被继承,不会被作为父类、基类。
将析构函数定义为虚函数,是最明智,最保险的一种做法,也是C++专家的惯用套路。
本文解析了C++中基类析构函数设置为虚函数的原因,介绍了多态机制的基本原理,并通过代码示例展示了若不使用虚析构函数可能带来的资源泄露问题。
2739

被折叠的 条评论
为什么被折叠?



