虚拟析构函数用例
Virtual destructor use cases
我读过一些文章,正如他们所说,主要的虚拟析构函数用例有:
-
派生的类可能具有来自堆的动态数据分配,即"拥有"该数据对象。所以,它们需要一些析构函数中的删除例程。通过base类指针删除需要所有派生类别中析构函数的
virtual
声明,直到那些具有动态数据分配的类别(baseclass也需要它( -
这个类有
virtual
方法。但我不清楚这一点。仅仅通过base类指针调用virtual
方法总是会产生最多的派生实现调用。他们唯一排除的规则是施工阶段。从字面上看,在此过程中,this
对象还不是派生的类型,即使稍后会是。好吧,销毁阶段呢?据我所知,这条规则是按后序排列的。不管层次结构中某个类的析构函数是否被声明为virtual
,在每个析构函数期间,this
指针都被当作该类类型使用,任何派生的都已经由于virtual
d-r而被销毁,或者没有被销毁(假设在某些设计中这可能是可以的(。也许是这样,为什么d-r必须是虚拟的?Vtable将具有派生的类的条目,并且从d-r调用某些基类别中的virtual
方法将导致UB?好的,但这个规则只适用于这个类调用d-r中的一些virtual
方法的情况,并且它们在派生的类中确实有实现。
我的观点是,也可能存在没有动态数据分配的情况,在所有层次结构中都没有虚拟方法,但仍然派生的析构函数可以在删除时执行一些关键任务(同步、解锁等(。我们需要基类中的虚拟d-r。这种情况可能是由于设计不好造成的。
但无论如何,一些公共类的开发人员不可能100%知道派生类是否会在d-r中使用一些虚拟方法,或者分配动态数据。那么,我正确地说,任何未声明为final
的公共类都必须声明d-r为虚拟的吗?只有final
关键字可以保证指向此类的任何指针始终是这种类型,因此可以安全地非虚拟删除。
如果通过指向基类的指针删除派生对象,则(并且仅限于此(基类析构函数必须是虚拟的。否则就是未定义的行为。没有其他相关规则。
如果这个类有一个虚拟函数,那么就不会引入任何开销。如果该类没有任何其他虚拟函数,则基类设计器必须考虑添加虚拟析构函数的运行时惩罚与该类的用户可能试图通过基类指针删除派生对象的风险之间的权衡。
这里有一个类似讨论的链接,标准报价
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 是否可以使用函数指针调用虚拟析构函数?
- 在没有动态内存的世界中,我是否需要虚拟析构函数?
- "虚拟""覆盖"析构函数
- 程序永远不会进入虚拟析构函数
- C++ std::vector 中的虚拟析构函数继承
- 哪种方法更适合处理虚拟析构函数?
- 拥有"受保护的非虚拟析构函数"与"受保护虚拟析构构函数"有什么好处
- 带有未解析外部元素的C++虚拟析构函数
- 即使基类和派生类只使用基元数据类型,我是否需要定义虚拟析构函数
- 从内部类的析构函数调用虚拟函数
- C++切片和虚拟析构函数
- C++虚拟继承、虚拟析构函数和 dynamic_cast<void*>
- 添加虚拟析构函数会使代码大小膨胀
- 应该是虚拟析构函数吗?但是怎么做呢?
- 虚拟析构函数将对象移出 rodata 部分
- 为什么虚拟类的析构函数不会自动添加到 vtable 中?
- 如何将 std::unique_ptr<Parent> 与具有受保护虚拟析构函数的只读父类一起使用
- DIRECTX9 中自定义顶点的虚拟析构函数
- 声明析构函数虚拟就足够了吗?