“override”关键字只是检查重写的虚拟方法吗?

时间:2021-05-11 22:28:29

As far as I understand, the introduction of override keyword in C++11 is nothing more than a check to make sure that the function being implemented is the overrideing of a virtual function in the base class.

据我所知,在c++ 11中引入override关键字只是为了确保正在实现的函数是基类中的虚函数的重写。

Is that it?

是它吗?

4 个解决方案

#1


191  

That's indeed the idea. The point is that you are explicit about what you mean, so that an otherwise silent error can be diagnosed:

这是确实的想法。关键是你要明确自己的意思,这样才能诊断出一个无声的错误:

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

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

The above code compiles, but is not what you may have meant (note the missing const). If you said instead, virtual int foo() override, then you would get a compiler error that your function is not in fact overriding anything.

上面的代码会编译,但不是您想要的(请注意丢失的const)。如果您说的是虚拟int foo()重写,那么您将得到一个编译器错误,您的函数实际上并没有覆盖任何东西。

#2


24  

Wikipedia quote:

*:

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.

重写特殊标识符意味着编译器将检查基类(es),以查看是否有一个具有此确切签名的虚函数。如果没有,编译器就会出错。

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

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

Edit (attempting to improve a bit the answer):

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

Declaring a method as "override" means that that method is intended to rewrite a (virtual) method on the base class. The overriding method must have same signature (at least for the input parameters) as the method it intends to rewrite.

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

Why is this necessary? Well, the following two common error cases are prevented:

为什么这是必要的吗?以下两种常见的错误可以避免:

  1. one mistypes a type in the new method. The compiler, unaware that it is intending to write a previous method, simply adds it to the class as a new method. The problem is that the old method is still there, the new one is added just as an overload. In this case, all calls towards the old method will function just as before, without any change in behavior (which would have been the very purpose of the rewriting).

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

  2. one forgets to declare the method in the superclass as "virtual", but still attempts to re-write it in a subclass. While this will be apparently accepted, the behavior won't be exactly as intended: the method is not virtual, so access through pointers towards the superclass will end calling the old (superclass') method instead of the new (subclass') method.

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

Adding "override" clearly disambiguates this: through this, one is telling the compiler that three things are expecting:

添加“override”可以清楚地消除歧义:通过此,可以告诉编译器有三件事情需要:

  1. there is a method with the same name in the superclass
  2. 在超类中有一个同名的方法
  3. this method in the superclass is declared as "virtual" (that means, intended to be rewritten)
  4. 超类中的这个方法被声明为“virtual”(这意味着要重写)
  5. the method in the superclass has the same (input*) signature as the method in the subclass (the rewriting method)
  6. 超类中的方法与子类中的方法(重写方法)具有相同的(输入*)签名

If any of these is false, then an error is signaled.

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

* note: the output parameter is sometimes of different, but related type. Read about covariant and contravariant transformations if interested.

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

#3


18  

Found "override" is useful when somebody updated base class virtual method signature such as adding an optional parameter but forgot to update derived class method signature. In that case the methods between the base and the derived class are no longer polymorphic relation. Without the override declaration, it is hard to find out this kind of bug.

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

#4


3  

Yes, this is so. It's a check to make sure one doesn't try an override and mess it up through a botched signature. Here's a Wiki page that explains this in detail and has a short illustrative example:

是的,是这样。这是一种检查,以确保一个人不会尝试重写,并通过一个拙劣的签名来搅乱它。这里有一个Wiki页面,详细解释了这一点,并有一个简短的示例:

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

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

#1


191  

That's indeed the idea. The point is that you are explicit about what you mean, so that an otherwise silent error can be diagnosed:

这是确实的想法。关键是你要明确自己的意思,这样才能诊断出一个无声的错误:

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

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

The above code compiles, but is not what you may have meant (note the missing const). If you said instead, virtual int foo() override, then you would get a compiler error that your function is not in fact overriding anything.

上面的代码会编译,但不是您想要的(请注意丢失的const)。如果您说的是虚拟int foo()重写,那么您将得到一个编译器错误,您的函数实际上并没有覆盖任何东西。

#2


24  

Wikipedia quote:

*:

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.

重写特殊标识符意味着编译器将检查基类(es),以查看是否有一个具有此确切签名的虚函数。如果没有,编译器就会出错。

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

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

Edit (attempting to improve a bit the answer):

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

Declaring a method as "override" means that that method is intended to rewrite a (virtual) method on the base class. The overriding method must have same signature (at least for the input parameters) as the method it intends to rewrite.

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

Why is this necessary? Well, the following two common error cases are prevented:

为什么这是必要的吗?以下两种常见的错误可以避免:

  1. one mistypes a type in the new method. The compiler, unaware that it is intending to write a previous method, simply adds it to the class as a new method. The problem is that the old method is still there, the new one is added just as an overload. In this case, all calls towards the old method will function just as before, without any change in behavior (which would have been the very purpose of the rewriting).

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

  2. one forgets to declare the method in the superclass as "virtual", but still attempts to re-write it in a subclass. While this will be apparently accepted, the behavior won't be exactly as intended: the method is not virtual, so access through pointers towards the superclass will end calling the old (superclass') method instead of the new (subclass') method.

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

Adding "override" clearly disambiguates this: through this, one is telling the compiler that three things are expecting:

添加“override”可以清楚地消除歧义:通过此,可以告诉编译器有三件事情需要:

  1. there is a method with the same name in the superclass
  2. 在超类中有一个同名的方法
  3. this method in the superclass is declared as "virtual" (that means, intended to be rewritten)
  4. 超类中的这个方法被声明为“virtual”(这意味着要重写)
  5. the method in the superclass has the same (input*) signature as the method in the subclass (the rewriting method)
  6. 超类中的方法与子类中的方法(重写方法)具有相同的(输入*)签名

If any of these is false, then an error is signaled.

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

* note: the output parameter is sometimes of different, but related type. Read about covariant and contravariant transformations if interested.

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

#3


18  

Found "override" is useful when somebody updated base class virtual method signature such as adding an optional parameter but forgot to update derived class method signature. In that case the methods between the base and the derived class are no longer polymorphic relation. Without the override declaration, it is hard to find out this kind of bug.

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

#4


3  

Yes, this is so. It's a check to make sure one doesn't try an override and mess it up through a botched signature. Here's a Wiki page that explains this in detail and has a short illustrative example:

是的,是这样。这是一种检查,以确保一个人不会尝试重写,并通过一个拙劣的签名来搅乱它。这里有一个Wiki页面,详细解释了这一点,并有一个简短的示例:

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

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