把类的析构函数写成虚函数的用意

原文链接

Cpp代码 
#include <iostream.h>
class Base 
{ 
public: 
Base() { mPtr = new int; } 
~Base() { delete mPtr; cout<<"Base::Destruction"<<endl;} 
private: 
  int* mPtr; 
} ;

class Derived : public Base 
{ 
public: 
  Derived() { mDerived = new long; } 
  ~Derived() { delete mDerived; cout<<"Derived::Destruction"<<endl;} 
private: 
  long* mDerived; 
} ;

void main() 
{ 
  Base* p = new Derived; 
  delete p; 
} 

 

 

输出结果只有:Base::Destruction
以上代码会产生内存泄露,因为new出来的是Derived类资源,采用一个基类的指针来接收,析构的时候,编译器因为只是知道这个指针是基类的,所以只将基类部分的内存析构了,而不会析构子类的,就造成了内存泄露,如果将基类的析构函数改成虚函数,就可以避免这种情况,因为虚函数是后绑定,其实就是在虚函数列表中,析构函数将基类的析构函数用实际对象的一组析构函数替换掉了,也就是先执行子类的虚函数再执行父类的虚函数,这样子类的内存析构了,父类的内存也释放了,就不会产生内存泄露。
 
应该为
#include <iostream.h>
class Base 
{ 
public: 
Base() { mPtr = new int; } 
virtual ~Base() { delete mPtr; cout<<"Base::Destruction"<<endl;} 
private: 
  int* mPtr; 
} ;

class Derived : public Base 
{ 
public: 
  Derived() { mDerived = new long; } 
  ~Derived() { delete mDerived; cout<<"Derived::Destruction"<<endl;} 
private: 
  long* mDerived; 
} ;

void main() 
{ 
  Base* p = new Derived; 
  delete p; 
} 

 

 
注:
1.析构函数其实是一个函数,不论子类还是父类,虽然可能看起来名字不一样。而且析构函数执行过程都是执行子类再到父类。
2.多态的时候一定要将析构函数写成虚函数,防止内存泄露,各个子类维护自己内部数据释放。
 
virtual 是实现多态的基础
它使得具体的函数跳转从编译时推迟到运行时然而构造函数的调用是编译器期间就决定的,因此它不能为虚
posted @ 2012-05-11 19:51  wangkangluo1  阅读(914)  评论(0编辑  收藏  举报