关于c ++:’override’关键字是否只是检查重写的虚方法?

Is the 'override' keyword just a check for a overridden virtual method?

据我所知,在C++ 11中引入EDCOX1的0个关键字,只不过是一个检查,以确保所实现的函数是EDOCX1 0在基类中的EDOCX1×2函数。

是这样吗?


这确实是个主意。关键是你要明确你的意思,这样就可以诊断出一个原本无声的错误:

1
2
3
4
5
6
7
8
9
10
11
12
struct Base
{
    virtual int foo() const;
};

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

上面的代码是编译的,但不是您的意思(请注意缺少的const)。如果您说的是virtual int foo() override,那么您会得到一个编译器错误,您的函数实际上没有覆盖任何内容。


维基百科引言:

The override special identifier means that the compiler will check the base class(es) to see if there is a virtual function with this exact signature. And if there is not, the compiler will error out.

http://en.wikipedia.org/wiki/c%2b%2b11显式覆盖和最终

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

将方法声明为"override"意味着该方法旨在重写基类上的(虚拟)方法。重写方法必须具有与其要重写的方法相同的签名(至少对于输入参数)。

为什么有必要这样做?好吧,下面两个常见的错误案例是可以避免的:

  • 在新方法中有一个类型输入错误。编译器没有意识到它打算写上一个方法,只是将它作为一个新方法添加到类中。问题是旧方法仍然存在,新方法只是作为重载添加的。在这种情况下,对旧方法的所有调用都将像以前一样工作,而行为没有任何变化(这正是重写的目的)。

  • 人们忘记将超类中的方法声明为"virtual",但仍然试图将其重新写入子类中。虽然这显然是可以接受的,但行为不会完全如预期的那样:方法不是虚拟的,因此通过指向超类的指针访问将结束调用旧的(超类)方法,而不是新的(子类)方法。

  • 添加"override"可以清楚地消除这一点:通过这个,我们可以告诉编译器有三件事需要处理:

  • 在超类中有一个同名的方法
  • 超类中的此方法声明为"virtual"(即,打算重写)
  • 超类中的方法与子类(重写方法)中的方法具有相同的(input*)签名。
  • 如果其中任何一个是错误的,那么就会发出错误信号。

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


    当有人更新了基类虚拟方法签名(如添加可选参数但忘记更新派生类方法签名)时,发现"override"非常有用。在这种情况下,基类和派生类之间的方法不再是多态关系。没有override声明,很难发现这种bug。


    是的,就是这样。这是一个检查,以确保不会尝试重写,并通过一个错误的签名将其搞乱。这是一个wiki页面,详细解释了这一点,并有一个简短的示例:

    http://en.wikipedia.org/wiki/c%2b%2b11显式覆盖和最终


    C++ 17标准草案

    在对C++ 17 N469标准草案中的所有EDCOX1×2命中进行了遍历之后,对EDCOX1×2标识符的唯一引用是:

    5 If a virtual function is marked with the virt-specifier override and does not override a member function of a
    base class, the program is ill-formed. [ Example:

    1
    2
    3
    4
    5
    6
    7
    8
    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
    }

    — end example ]

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