有关虚(virtual)析构函数

记得有一次在面试的时候被问到虚析构函数的作用,当时回答得不是很好,故现在想重新整理下。

先看下下面的代码:

#include  < iostream >
using   namespace  std;

class  Base
{
public :
    Base(){cout
<< " Base::constructor is called! " << endl;}
    
~ Base(){cout << " Base::destructor is called! " << endl;} // 大家关键是看这句
     virtual   void  f(){cout << " Base::f() is called! " << endl;};
};

class  Derived: public  Base
{
public :
    Derived(){cout
<< " Derived::constructor is called! " << endl;}
    
~ Derived(){cout << " Derived::destructor is called! " << endl;}
    
virtual   void  f(){cout << " Derived::f() is called! " << endl;}
};

int  main()
{
    Base 
* pBase;
    pBase
= new  Derived();
    cout
<< " ************************************* " << endl;
    pBase
-> f();
    cout
<< " ************************************* " << endl;
    delete pBase;

    system(
" pause " );
    
return   0 ;
}

大家猜猜输出结果如何?

以下是输出结果:

Base::constructor is called!

Derived::constructor is called!

*************************************

Derived::f() is called!

*************************************

Base::destructor is called!

请按任意键继续. . .

 

没错,也许你已经看出问题的所在了。C++明确指出,当一个继承类经由一个基类的指针删除时,而该基类包含的是一个非虚析构函数,其结果是未定义的(实际执行时通常发生的是继承类的独有成分没有被销毁。这个后果很严重,会造成内存泄漏。

不过解决这个问题的方法也很简单。只要你在Base类的析构函数~Base()前加上一个virtual就行了。这时通过基类指针删继承类会得到你期望的结果。

如下是使用了虚析构函数后的输出结果:

Base::constructor is called!

Derived::constructor is called!

*************************************

Derived::f() is called!

*************************************

Derived::destructor is called!

Base::destructor is called!

请按任意键继续. . .

哈哈,有意思吧。以后在通过基类指针删继承类时你可要注意了啊!别忘了在基类声明一个虚析构函数!

 

问题还没有结束。我们知道,如果定义了一个普通的纯虚(pure-virtual)函数的话,这个纯虚(pure-virtual)函数是可以不带函数体的。但这并对纯虚(pure-virtual)析构函数来说并不成立。如果我们在基类中将析构函数定义为pure-virtual类型,那么我们也必须为这个函数提供一份实现。

下面是代码说明:

class  Base
{
public :
    Base(){cout
<< " Base::constructor is called! " << endl;}
    
virtual   ~ Base() = 0 ; // 这里是会出现问题的,如果这个函数确实什么也不想做,
                    
// 那么至少定义为virtual ~Base()=0{}。
     virtual   void  f(){cout << " Base::f() is called! " << endl;};
};

好了,就说到这吧!虚析构函数的用法虽然简单,但它在面向对象程序设计中却是一个重要的技巧。那我们以后在这方面也要多加注意了哦!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值