规则:如果一个类有可能被继承,那么请为它加上一个虚的析构函数,即使这个析构函数一行代码也没有。
0. 引子
为什么这样说?先看一个例子。先定义3个类:
class CBase { public: long m; long n; long o; CBase() { m = 1; n = 2; o = 3; } void Do(int y); ~CBase(); }; void CBase::Do(int y) { int x; x = n; printf("%s, m ", __FUNCTION__, x + y); } CBase::~CBase() { printf("%s ", __FUNCTION__); } class CChild: public CBase { public: virtual ~CChild(); }; CChild::~CChild() { printf("%s ", __FUNCTION__); } class CGrandChild:public CChild { public: ~CGrandChild(); }; CGrandChild::~CGrandChild() { printf("%s ", __FUNCTION__); }
接着声明变量:
CBase *b; CChild *c; CGrandChild *g;
然后执行代码:
c = new CChild; b=c; printf("b=%08XH, c=%08XH ", (unsigned)b, (unsigned)c); delete b;
会有什么结果呢?在笔者的计算上执行结果如下:
b=00340F84H, c=00340F80H //注意两者不相等, b=c+4 CBase::~CBase //接着出现b指针内存释放错误。