9. 虚析构函数
如果一个类可能被继承,并且会通过基类指针来删除(delete)派生类的对象,那么他的析构函数必须是虚函数。否则只会调用基类的析构函数,不会调用派生类的析构函数,导致部分资源泄露。
虚析构函数的作用是保证在使用 delete 来销毁对象是一定能够调用该类的析构函数来防止资源丢失。
语法
class 类名{
// 声明虚析函数。
virtual ~类名(void){...}
};
示例
// filename: v_decons.cpp
#include <iostream>
using namespace std;
#define PI (3.1415926)
// 抽象类
class Shape{ // 抽象类(Abstract Class);
public:
virtual ~Shape() {cout << "~Shape()" << endl;};
// 纯虚函数的声明
virtual void moveTo(float x, float y)=0;
};
// 点类(描述一个点的位置,面积等信息)
class Point: public Shape {
public:
Point(float ax=0, float ay=0):x(ax), y(ay) {
cout << "Point(" << x << "," << y << ")\n";
}
~Point() {
cout << "~Point(" << x << "," << y << ")\n";
}
void moveTo(float new_x, float new_y) {
x = new_x; y = new_y;
}
public:
float x;
float y;
};
// 圆类(描述圆的位置、半径、面积等信息)
class Circle : public Point {
public:
Circle(float ax, float ay, float radius)
: Point(ax, ay), r(radius) {
cout << "Circle(" << x << "," << y << "," << r << ")\n";
}
~Circle() {
cout << "~Circle(" << x << "," << y << "," << r << ")\n";
}
public:
float r; // 半径
};
int main(int argc, char * argv[]) {
Point * p;
p = new Point(1, 2);
delete p;
Shape *p2;
p2 = new Circle(3, 4, 5);
delete p2; // 调用圆的析构函数
cout << "程序结束!" << endl;
return 0;
}
编译和运行结果如下:
weimz@mzstudio:~$ g++ -o v_decons v_decons.cpp
weimz@mzstudio:~$ ./v_decons
Point(1,2)
~Point(1,2)
Point(3,4)
Circle(3,4,5)
~Circle(3,4,5)
~Point(3,4)
程序结束!
实验
将上述示例的抽象类 Shape 的 虚析构函数 virtual ~Shape(){...} 改为 ~Shape(){...}, 然后运行此示例,查看器运行结果,想想为什么?