假设我有:
struct Base
{
/**/ virtual /**/ ~Base() {/*..*/}
// ...
};
struct Derived : Base
{
~Derived() /* override */ {/*..*/}
// ...
};
当一个类从另一个类继承时,此处的重写可帮助我确保自己实现了中真正存在的功能Base
。在上述这种情况下,Derived
class的名称不同于Base
,因此其析构函数的编写方式也不同。
我的问题是,如果要使用它override
,该在哪里使用?我在哪里真正实现Base
Derived类的函数?
首先,“ override”关键字仅表示“此函数在某些基类中被标记为具有病毒性”,仅此而已。它也可以应用于析构函数。但是析构函数是特殊的,正常规则不适用于它们。对于例如析构函数Derived
,命名~Derived()
与析构函数匹配Base
,命名~Base()
,即使形式上,他们有不同的名称(或者是吗?什么是这里的名字呢?)。
析构函数与典型函数之间的另一个区别是,无论实现如何,析构函数总是在继承链中调用。因此,您不能“替换”破坏,而只能“扩展”破坏。请注意(与普通函数不同)从派生析构函数调用基类析构函数是一个错误。
链接销毁调用从您当前所指的类开始。我的意思是
Base* inst = new Derived();
delete inst;
将调用~Base()
,因为变量inst
是Base*
,即使它是从一个派生类中构造。此时适用“虚拟逻辑”:如果~Base()
不是虚拟逻辑,则正常的销毁过程将触发Base
类,而不会意识到实际的对象是Derived*
,即执行了~Base()
所有其父描述符(在这种情况下没有)。错了 但是,如果它是虚拟的,那么它将实际上跳到正确的类Derived
,并调用正确的销毁过程:首先是~Derived()
,然后是~Base()
。看到这个godbolt.org 并尝试:在基本析构函数中添加和删除“虚拟”以查看区别(仅查看左列,带有彩色背景的行是实际被调用的行)。
总而言之:是的,您可以使用~Derived() override {}
。我总是在适当的地方使用“覆盖”,很高兴知道哪些函数是从虚函数派生的。经验法则是:如果Base
是虚拟的(意味着任何函数都是虚拟的),则其析构函数也应该是虚拟的。请牢记这一点,它将帮助您避免一些问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句