虚拟析构函数用例
Virtual destructor use cases
我读过一些文章,正如他们所说,主要的虚拟析构函数用例是:
derived classes 可能有来自堆的动态数据分配,即 "own" 那个数据对象。所以,他们需要在析构函数中有一些删除例程。通过 base class 指针删除需要 virtual
在所有 derived class 中声明析构函数,直到那些具有动态数据分配(base class也需要)
这个class有virtual
个方法。但这对我来说还不清楚。仅通过 base class 指针调用 virtual
方法总是会导致最 derived 实现调用。他们唯一排除该规则的是施工阶段。从字面上看,在此期间 this
对象还不是 derived 类型,即使以后会是。好的,销毁阶段呢?据我了解,规则是倒序的。无论如何,层次结构中某些 class 的析构函数被声明为 virtual
,在每个析构函数 this
指针被用作此 class 类型时,任何派生都已被销毁由于 virtual
d-r,或未被破坏(假设在某些设计中可能没问题)。可能是这样,为什么d-r一定是虚的呢? Vtable 将包含 derived class 的条目,并从 d-r 调用某些 base class 中的 virtual
方法会导致UB吗?好的,但是这个规则只适用于这个 class 在 d-r 中调用一些 virtual
方法的情况,并且它们在 derived classes 中确实有实现.
我认为,也可能存在没有动态数据分配的情况,所有层次结构中都没有虚方法,但派生的析构函数仍然可以在删除时执行一些关键任务(同步、解锁等)。我们需要在 base class 中使用虚拟 d-r。可能这种情况是设计不良的结果。
但是无论如何,一些 public class 的开发者不能 100% 知道,如果派生 class 是否会在 d-r 中使用一些虚拟方法,或者分配动态数据。所以,我说得对吗,任何未声明为 final
的 public class 都必须将 d-r 声明为虚拟的?只有 final
关键字保证任何指向此 class 的指针将始终是这种类型,因此可以安全地非虚拟地删除。
如果通过指向基 class 的指针删除派生对象,那么(并且只有在那时)基 class 析构函数必须是虚拟的。否则就是undefined behaviour。暂无其他相关规定。
如果 class 无论如何都有一个虚函数,那么就不会引入任何开销。如果 class 没有任何其他虚函数,那么基础 class 设计者必须考虑增加虚拟析构函数的运行时惩罚与 [= 的用户的风险之间的权衡18=] 可能会尝试通过基 class 指针删除派生对象。
Here is a link to a similar discussion, with Standard quotes
我读过一些文章,正如他们所说,主要的虚拟析构函数用例是:
derived classes 可能有来自堆的动态数据分配,即 "own" 那个数据对象。所以,他们需要在析构函数中有一些删除例程。通过 base class 指针删除需要
virtual
在所有 derived class 中声明析构函数,直到那些具有动态数据分配(base class也需要)这个class有
virtual
个方法。但这对我来说还不清楚。仅通过 base class 指针调用virtual
方法总是会导致最 derived 实现调用。他们唯一排除该规则的是施工阶段。从字面上看,在此期间this
对象还不是 derived 类型,即使以后会是。好的,销毁阶段呢?据我了解,规则是倒序的。无论如何,层次结构中某些 class 的析构函数被声明为virtual
,在每个析构函数this
指针被用作此 class 类型时,任何派生都已被销毁由于virtual
d-r,或未被破坏(假设在某些设计中可能没问题)。可能是这样,为什么d-r一定是虚的呢? Vtable 将包含 derived class 的条目,并从 d-r 调用某些 base class 中的virtual
方法会导致UB吗?好的,但是这个规则只适用于这个 class 在 d-r 中调用一些virtual
方法的情况,并且它们在 derived classes 中确实有实现.
我认为,也可能存在没有动态数据分配的情况,所有层次结构中都没有虚方法,但派生的析构函数仍然可以在删除时执行一些关键任务(同步、解锁等)。我们需要在 base class 中使用虚拟 d-r。可能这种情况是设计不良的结果。
但是无论如何,一些 public class 的开发者不能 100% 知道,如果派生 class 是否会在 d-r 中使用一些虚拟方法,或者分配动态数据。所以,我说得对吗,任何未声明为 final
的 public class 都必须将 d-r 声明为虚拟的?只有 final
关键字保证任何指向此 class 的指针将始终是这种类型,因此可以安全地非虚拟地删除。
如果通过指向基 class 的指针删除派生对象,那么(并且只有在那时)基 class 析构函数必须是虚拟的。否则就是undefined behaviour。暂无其他相关规定。
如果 class 无论如何都有一个虚函数,那么就不会引入任何开销。如果 class 没有任何其他虚函数,那么基础 class 设计者必须考虑增加虚拟析构函数的运行时惩罚与 [= 的用户的风险之间的权衡18=] 可能会尝试通过基 class 指针删除派生对象。
Here is a link to a similar discussion, with Standard quotes