'override' 关键字只是检查覆盖的虚拟方法吗?

新手上路,请多包涵

据我了解,在 C++11 中引入 override 关键字无非是检查以确保正在实现的功能是 overridevirtual 基类中的函数。

是这样吗?

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

阅读 605
2 个回答

确实是这样的想法。关键是您要明确说明您的意思,以便可以诊断出其他无声的错误:

 struct Base
{
    virtual int foo() const;
};

struct Derived : Base
{
    virtual int foo()   // whoops!
    {
       // ...
    }
};

上面的代码可以编译,但不是您的意思(注意缺少的 const )。如果您改为 virtual int foo() override ,那么您将收到编译器错误,表明您的函数实际上并未覆盖任何内容。

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

维基百科引用:

覆盖特殊标识符意味着编译器将检查基类以查看是否存在具有此确切签名的虚函数。如果没有,编译器会出错。

http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final

编辑(试图改进一点答案):

将方法声明为“覆盖”意味着该方法 旨在 重写基类上的(虚拟)方法。重写方法必须与它打算重写的方法具有相同的签名(至少对于输入参数)。

为什么这是必要的?好吧,防止了以下两种常见的错误情况:

  1. 一个人在新方法中打错了一个类型。编译器不知道它打算编写以前的方法,只是将其作为新方法添加到类中。问题是旧方法仍然存在,新方法只是作为重载添加。在这种情况下,对旧方法的所有调用都将像以前一样运行,而不会改变行为(这本来就是重写的目的)。

  2. 忘记将超类中的方法声明为“虚拟”,但仍试图在子类中重写它。虽然这显然会被接受,但行为不会完全符合预期:该方法不是虚拟的,因此通过指向超类的指针访问将结束调用旧的(超类’)方法而不是新的(子类’)方法。

添加“覆盖”清楚地消除了这一点:通过这个,一个人告诉编译器期待三件事:

  1. 超类中有同名方法
  2. 超类中的这个方法被声明为“虚拟”(这意味着,打算被重写)
  3. 超类中的方法与子类中的方法(重写方法)具有相同的(输入*)签名

如果其中任何一个为假,则发出错误信号。

\* 注意:输出参数有时是不同的,但相关的类型。如果有兴趣,请阅读协变和逆变转换。

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

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