析构函数和构造函数的功能恰恰相反,也就是说,析构函数是完成对分配内存资源的回收!下面我们分两种情况来讨论:
(1)非显式的调用析构函数(2)显式的调用析构函数
一.非显式的调用析构函数
(1)当类中不含有在堆中分配的内存时,系统在对象消失后会自动的调用该对象的析构函数
(2)当类中含有new/malloc等在堆中分类的内存的时候,我们必须用delete/free释放掉分配的内存,析构函数才会被调用,如果没有delete,那么就会造成内存泄漏。举例说明:
//test C++destructor
#include <iostream>
using namespace std;
class A
{
public:A (){cout<<"constructor implement"<<endl;}~A(){cout<<"destructor implement"<<endl;}
private:int m_a;
};
void main()
{A *a1 = new A(); //在堆中分配内存A a2;//在栈上分配内存delete a1;
}
执行结果:
二.显式的调用析构函数
许多类不需要显式析构函数,尤其是具有构造函数的类不一定需要定义自己的析构函数,仅仅在有些工作需要析构函数完成时,才需要析构函数。在这里,我们先不讲很多,具体的可以参见博客:
http://www.cppblog.com/lf426/archive/2008/04/12/46909.html
http://www.cnblogs.com/fangyukuan/archive/2010/08/28/1811119.html
下面再说一下在多重继承中基类中为什么要把析构函数加上virtual关键字。看下面的代码:
//test C++destructor
#include <iostream>
using namespace std;
class A
{
public:A (){cout<<"A constructor implement"<<endl;pa = new int;}~A(){cout<<"A destructor implement"<<endl;}
private:int m_a;int *pa;
};class B: public A
{
public:B(){cout<<"B constructor"<<endl;pb = new int;}~B(){cout<<"B destructor"<<endl;}
private:int m_b;int *pb;};
void main()
{
// A *a1 = new A();
// A a2;
// delete a1;A *b = new B;delete b;}
运行结果为:
可以发现,只有基类的析构函数被调用,派生类没有被调用,这势必发生内存泄漏。因此需要在基类的析构函数前面加上virtual,这样的目的是发生动态绑定,当delete b时,首先能调用派生类的析构函数。