关于c ++:虚拟析构函数用例

Virtual destructor use cases

我读过一些文章,正如他们所说,主要的虚拟析构函数用例是:

  • 派生类可能具有来自堆的动态数据分配,即"拥有"该数据对象。所以,它们需要析构函数中的一些删除例程。通过基类指针删除要求在所有派生类中声明virtual析构函数,直到那些具有动态数据分配的类(基类也要求声明)为止。

  • 这个类有virtual方法。但这对我来说并不清楚。仅仅通过基类指针调用virtual方法总是会导致最派生的实现调用。他们唯一排除的规则是构造阶段。字面上,在这个过程中,this对象还不是派生类型,即使以后会是。好吧,破坏阶段呢?据我所知,这条规则是逆向的。无论是层次结构中某个类的析构函数声明为virtual,在每个析构函数中,this指针被用作类类型,任何派生的都已经因为virtuald-r而被销毁,或者没有被销毁(在某些设计中,假设可以)。也许是这样,为什么D-R必须是虚拟的?vtable将具有派生类的条目,并且从D-R调用某些基类中的virtual方法将导致ub?好的,但是这个规则只适用于这个类在D-R中调用一些virtual方法,并且它们确实在派生类中实现的情况。

我的观点是,也可能存在没有动态数据分配、所有层次结构中没有虚拟方法的情况,但是派生的析构函数在删除时可能会执行一些关键任务(同步、解锁等)。我们需要在基类中使用虚拟D-R。可能是这样的情况是不良设计的结果。

但是无论如何,一些公共类的开发人员不能100%地知道派生类是否会在D-R中使用某些虚拟方法,或者分配动态数据。那么,我是否正确地说,任何没有声明为final的公共类都必须声明d-r为虚拟类?只有final关键字才能保证指向此类的任何指针始终是这种类型,因此可以安全地非虚拟地删除。


如果通过指向基类的指针删除派生对象,则(并且仅限于此)基类析构函数必须是虚拟的。否则,这是未定义的行为。没有其他相关规则。

如果类无论如何都有一个虚函数,那么就不会引入开销。如果类没有任何其他虚拟函数,则基类设计器必须考虑在添加虚拟析构函数的运行时惩罚与类用户可能试图通过基类指针删除派生对象的风险之间进行权衡。

下面是一个类似讨论的链接,带有标准引号