为了账号安全,请及时绑定邮箱和手机立即绑定

“ override”关键字是否只是对覆盖的虚拟方法的检查?

“ override”关键字是否只是对覆盖的虚拟方法的检查?

C++
暮色呼如 2019-12-09 14:36:17
据我了解,overrideC ++ 11 中关键字的引入无非是一项检查,以确保所实现override的virtual函数是基类中函数的作用。是吗
查看完整描述

3 回答

?
Qyouu

TA贡献1786条经验 获得超11个赞

确实是这个主意。关键是您要清楚自己的意思,以便可以诊断出其他无提示的错误:


struct Base

{

    virtual int foo() const;

};


struct Derived : Base

{

    virtual int foo()   // whoops!

    {

       // ...

    }

};

上面的代码可以编译,但不是您想要的(请注意缺少的内容const)。如果改为,virtual int foo() override则将出现编译器错误,即您的函数实际上并未覆盖任何内容。


查看完整回答
反对 回复 2019-12-09
?
湖上湖

TA贡献2003条经验 获得超2个赞

维基百科报价:


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


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


编辑(尝试改善答案):


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


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


一个人在新方法中输入了错误的类型。编译器不知道要编写先前的方法,只是将其作为新方法添加到类中。问题在于旧方法仍然存在,新方法只是作为重载而添加。在这种情况下,对旧方法的所有调用将像以前一样起作用,而行为没有任何变化(这正是重写的目的)。


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


添加“ override”显然消除了歧义:通过这一点,一个是告诉编译器期望的三件事:


在超类中有一个同名的方法

该超类中的此方法被声明为“虚拟”(意味着,将被重写)

超类中的方法具有与子类中的方法(重写方法)相同的(input *)签名

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


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


查看完整回答
反对 回复 2019-12-09
?
杨魅力

TA贡献1811条经验 获得超6个赞

C ++ 17标准草案


在仔细override研究了C ++ 17 N4659标准草案中的所有内容之后,我可以找到的对该override标识符的唯一参考是:


5如果虚拟函数被virt-specifier覆盖标记,并且没有覆盖基类的成员函数,则程序格式错误。[示例:


struct B {

  virtual void f(int);

};


struct D : B {

  virtual void f(long) override; // error: wrong signature overriding B::f

  virtual void f(int) override;  // OK

}

—结束示例]


所以我认为可能炸毁错误的程序实际上是唯一的效果。


查看完整回答
反对 回复 2019-12-09
  • 3 回答
  • 0 关注
  • 477 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信