是“越权”的关键字只是检查了重写的虚方法?

问题描述 投票:196回答:5

据我了解,在C ++ 11引进override关键字的无非是更多的检查,以确保正在实施的功能是在基类override功能的virtualing。

是不是这样?

c++ c++11 inheritance override virtual-method
5个回答
235
投票

这是确实的想法。问题的关键是,你明确你的意思,让原本沉默的错误可以诊断:

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

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

上面的代码编译,但不是你的意思是不是(注意失踪const)。如果你不是说,virtual int foo() override,那么你会得到一个编译错误,你的功能其实也不是什么压倒一切。


32
投票

维基百科报价:

超驰特殊标识符意味着,编译器将检查基类(ES),以查看是否存在与此完全相同的签名的虚函数。如果没有,编译器会报错了。

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

编辑(试图改善了一下回答):

声明一个方法为“覆盖”是指该方法的目的是重写在基类(虚拟)方法。压倒一切的方法必须具有相同的签名(至少对于输入参数),因为它打算重写方法。

为什么是这个必要吗?好了,则无法进行以下两种常见的错误情况:

  1. 一个输入错误在新的方法的类型。编译器,不知道它是打算写以前的方法,简单地把它添加到类作为一个新的方法。问题是,旧的方法仍然存在,新的一个添加就像过载。在这种情况下,朝老方法的所有调用将像以前一样只是功能,无需任何行为上的变化(这将是重写的真正目的)。
  2. 一个忘记申报方法在超类中为“虚拟”,但仍试图将其在子类中重新写。虽然这将是明显接受的行为将不完全像预期一样:该方法不是虚拟的,所以通过指针访问朝着超将结束调用旧的(超类的)方法,而不是新的(子类“)的方法。

添加“越权”显然这个歧义消除:通过这个,一个是告知三件事期待的编译:

  1. 有一个在超类中的同名方法
  2. 在超类中该方法被声明为“虚拟”(即装置,旨在被重写)
  3. 在超类中的方法具有相同的(输入*)签名子类中的方法(改写方法)

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

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


26
投票

发现“覆盖”是当有人更新基类的虚方法签名如添加一个可选参数,但忘了更新派生类的方法签名是有用的。在这种情况下,基部和派生类之间的方法不再多态的关系。如果没有重写声明,这是很难找出这种错误。


5
投票

是的,这是如此。这是一个检查,以确保一个不试图通过一个拙劣的签名的倍率,搞砸了。下面是说明对此进行了详细和有一个很短说明性的例子一个Wiki页面:

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


1
投票

C ++ 17标准草案

override去在所有C++17 N4659 standard draft命中之后,仅供参考我能找到的override标识符是:

5如果一个虚拟函数标有VIRT说明符倍率和不覆盖的基类的成员函数,是形成不良的节目。 [实施例:

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
}

- 端示例]

所以我认为可能吹错了程序实际上是唯一的影响。

© www.soinside.com 2019 - 2024. All rights reserved.