析构函数和构造函数的功能恰恰相反,也就是说,析构函数是完成对分配内存资源的回收!下面我们分两种情况来讨论:
(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时,首先能调用派生类的析构函数。