虚析构函数

来源:互联网 发布:秃子扳机数据图 编辑:程序博客网 时间:2024/05/16 06:51
 

所谓虚析构函数就是用virtual关键字修饰的析构函数。比如:

Class   A

{

         public:

                   virtual ~A();

};

这样的就是虚析构函数。

那么就出现了一个问题,为什么要使用虚析构函数呢?请看下面这个例子:

class  A

{

         public:

                   A();

                 ~A();

};

 

A::A()

{

         cout<<”A()”<<endl;

}

 

A::~A()

{

         cout<<”~A()”<<endl;

}

 

class B : public A

{

         public:

                   B();

                   ~B();

};

 

B::B()

{

         cout<<”B()”<<endl;

}

 

B::~B()

{

         cout<<”~B()”<<endl;

}

 

int main()

{

         A *pa;

         B *pb;

 

         pb = new B;

         pa = pb;

         delete pa;

 

return 0;

}

发动你那上帝赐予的智商高达300的大脑思考一下,这段看似简单的程序的输出结果是什么。再去自己编程验证一下,看计算机的大脑和你的是否一样。

如果猜的不错的话(这显然是废话啊),是不是很多人猜想会输出:

A()

B()

~B()

~A()

那只有恭喜你又取得了进步,因为你猜错了!程序的实际输出结果是:

A()

B()

~A()

是不是很诡异啊?明明是调用了B的构造函数,却没有调用到B的析构函数。不会是编译器出问题了吧?告诉你一个真理,写编译器的哥们儿不是一般的高手,他们是很牛的一群人。至于牛到什么程度,反正不是你我在目前这个阶段能望其项背的,所以不用怀疑编译器。程序之所以输出这样的结果,是因为试图通过一个基类型的指针来删除派生类对象。释放这个指针所指向的内存区域时,只会调到基类A的析构函数,这就是语法规则。

这肯定不是我们想要的啊,因为通常情况下B的析构函数肯定不是这么简单(实际上这只析构函数是没有意义的,举例需要啊),里面通常是是释放构造函数申请的内存,调不到B的析构,就造成了内存泄露了。怎么解决这个问题呢?

这就到重点了(说了这么多才到重点,正是绕啊!汗~~~),利用虚析构就可以解决这个问题。在A的析构函数之前添加virtual关键字即可。自己验证一下,可以看到输出结果为:

A()

B()

~B()

~A()

原创粉丝点击