base class类virtual析构函数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了base class类virtual析构函数相关的知识,希望对你有一定的参考价值。
了解为什么base class的析构函数必须virtual声明,首先我们得知道pure virtual函数,impure-virtual函数与non-virtual函数在继承体系中所具有的作用。
我们知道继承中,有接口继承与实现继承。
Base class中pure virtual函数代表了接口继承,该函数必须在derived class中重新声明,但是它也可以拥有自己的实现。
Base class中impure-virtual函数则代表了接口继承且其可有自己的缺省声明,在derived class中可重新声明,若不声明则使用其缺省声明。
Base class中non-virtual函数则代表了接口继承且强制继承实现。
通过上述我们知道,若一个class为base class则其肯定被继承。若其析构函数为non-virtual函数,在下面代码中会出现问题:
class Base{
public:
Base();
~Base();
...
}
class Base: public A{...};
class Base: public B{...};
class Base: public C{...};
Base* GetBase(); //返回一个指针, Base派生类的动态分配对象
Base* prk = GetBase();
...
delete ptk;
在上述对象中,我们返回了一个派生类的实例化对象,然后初始化一个base class指针并指向这个对象。这时如果我们delete这个指针,我们会发现,这个对象的base class部分被删除,而derived class部分依然存在,这就造成了内存泄漏并破坏了数据的结构。而如果将base class的析构函数定义为了impure-virtual函数,则我们发现删除指针时所有内存全部释放。
根据上文所说的virtual函数在继承中的作用,基类中的析构函数如果是virtual的话则代表的其派生类中的析构函数是可重新声明的,若不声明则默认使用其缺省声明。若析构函数是non-virtual的话则说明其派生类的析构函数不可重新声明,且必须使用其基类的定义,则在上述的代码中调用派生类的析构函数时实际等于调用了基类的析构函数,故释放内存时则只删除了基类部分,派生类部分并没有删除。相反,派生类的析构函数是可重新声明的话,则调用时派生部分会得
到调用。
若类不为base class,加入virtual函数也是错误行为,具体结束下文再论。
以上是关于base class类virtual析构函数的主要内容,如果未能解决你的问题,请参考以下文章
警告: deleting object of polymorphic class type which has non_virtual destructor