重写析构函数 C

新手上路,请多包涵

从 C++ 常见问题解答:

[11.4] 我可以为我的班级重载析构函数吗?不。

我意识到这意味着您不能更改返回类型、参数的类型或参数的数量。我可能会对单词的语法感到困惑,但是是否可以 覆盖 父级的析构函数?

 class Child : public Parent {
public:
    virtual Parent::~Parent() {
        // New definition
    }
};

就此而言,它是递归的吗?

 class Grandchild : public Child {
public:
    Child::Parent::~Parent() {
        // An even newer definition
    }
};

我已经阅读了 这篇 文章和一篇 相关文章,这让我觉得因为析构函数不是继承的,它们不能被覆盖,但我从未见过它明确说明。

编辑:我改变了这个以反映我想覆盖父析构函数的事实,注意孩子和孙子覆盖〜Parent()。

我这样做的主要原因是为了维护 Parent 的接口,同时改变它的销毁方式(子类的全部原因)。我将有其他东西来管理所有 Parent 的创建,并在我选择的稍后时间显式调用它们的析构函数。

原文由 Danny A 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 931
2 个回答

我可能对单词的语法感到困惑

不,你绝对不是——这是两件截然不同的事情。

但是可以覆盖析构函数吗?

是的,事实上在很多情况下你 必须 这样做。为了使它适用于多态对象,您需要将基类析构函数声明为 virtual ,但是:

 Parent const& p = Child();

将在范围末尾正确调用 p.~Child() 因为 Parent::~Parent 是虚拟的。

原文由 Konrad Rudolph 发布,翻译遵循 CC BY-SA 3.0 许可协议

是的:你可以拥有 virtual 析构函数,唯一的原因是在派生类中覆盖它们。

它看起来像这样:

 class Parent {
public:
    virtual ~Parent();
};

class Child : public Parent {
public:
    virtual ~Child();
};

class Grandchild : public Child {
public:
    ~Grandchild(); // virtual is inherited here
};

请注意,析构函数不像普通函数那样被 名称 覆盖,因为名称始终是您要销毁其实例的类的名称。

另请注意,父类的析构函数也总是被调用,因此您不需要复制它们的清理代码:详细阅读成员对象和基类子对象的构造和销毁顺序。


术语

  • 重写 函数意味着在派生类中实现基类 virtual 函数。您根本无法更改签名(使用协变返回类型除外)。因此, 覆盖 总是与继承的虚函数具有相同的签名。
  • 重载 一个函数意味着实现多个具有相同名称(并且在某种意义上相同范围)的函数。因此, 重载 总是与其他同名的重载具有 不同 的签名,与虚拟调度没有直接关系,也不一定是继承的。

原文由 Useless 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题