C++中基类的析构函数不是虚函数,会带来什么问题!!
如下例:
#include <iostream> using namespace std; class Father { public: Father(){cout<<"contructor Father!"<<endl;}; ~Father(){cout<<"destructor Father!"<<endl;}; }; class Son:public Father { public: Son(){cout<<"contructor Son!"<<endl;}; ~Son(){cout<<"destructor Son!"<<endl;}; }; int main() { Father *pfather=new Son; delete pfather; pfather=NULL; return 0; }
运行结果:
contructor Father!
contructor Son!
destructor Father!
(1)基类的的析构函数不是虚函数的话,删除指针时,只有其类的内存被释放,派生类的没有。这样就内存泄漏了。
(2)析构函数不是虚函数的话,直接按指针类型调用该类型的析构函数代码,因为指针类型是基类,所以直接调用基类析构函数代码。
(3)delete是删除指针p指向的实例,p指针本身依然存在,delete后将p置为空值是常用做法,空值一般写成NULL宏,其实就是0。因为内存0位置是不允许访问的,delete 0操作编译器可以判断是错误操作不会执行,因此将p置为空值0是很安全的做法。
(4)当基类指针指向派生类的时候,如果析构函数不声明为虚函数,在析构的时候,不会调用派生类的析构函数,从而导致内存泄露。
(5)子类对象创建时先调用父类构造函数然后在调用子类构造函数,在清除对象时顺序相反,所以delete p只清除了父类,而子类没有清除
总结:
#include <iostream> using namespace std; class Father { public: Father(){cout<<"contructor Father!"<<endl;}; virtual ~Father(){cout<<"destructor Father!"<<endl;}; }; class Son:public Father { public: Son(){cout<<"contructor Son!"<<endl;}; ~Son(){cout<<"destructor Son!"<<endl;}; }; int main() { Father *pfather=new Son; delete pfather; pfather=NULL; return 0; }
结果:
contructor Father!
contructor Son!
destructor Son!
destructor Father!