覆盖纯虚函数时使用 override 有什么意义吗?

Is there any point in using `override` when overriding a pure virtual function?

例如:

class Base {
  virtual void my_function() = 0;
};

class Derived : Base {
  void my_function() override;
};

据我了解,override 关键字用于确保我们在覆盖的函数中具有正确的签名,这似乎是它的唯一用途。

但是,在纯虚函数的情况下,如果我们在 Derived class(或 Base class 中使用不正确的签名,编译器会抛出错误,具体取决于人们如何看待事物)。那么,在 Derived::my_function() 声明的末尾添加 override 有什么意义吗?

However, in the case of a pure virtual function, the compiler would throw an error if we used an incorrect signature in the Derived class

不,这个编译:

class Base {
  virtual void my_function() = 0;
};

class Derived : Base {
  void my_function(int);
//                 ^^^ mistake!
};

虽然这不是:

class Base {
  virtual void my_function() = 0;
};

class Derived : Base {
  void my_function(int) override;
};

error: void Derived::my_function(int) marked override, but does not override


您所说的错误仅在实例化时发生 Derived - override 允许您更早地发现错误并使 Derived clearer/more 的定义可读.

是的,始终如一地使用 override 关键字作为防御措施是个好主意。

Base 的作者决定 my_function 不再是纯虚拟的,并且它应该采用新参数时,考虑重新设计。使用 override 编译器将捕获此问题;没有 override 你的 Derived class 会继续编译。

是的!!

它提高了代码的清晰度override 关键字可防止歧义并传达重写其基本 class 方法的含义。

防止可能的意外使用: 将来,如果 base class 更改方法签名(此处为 virtual),它会强制 derive class 进行相应更改。 (编译器错误)。否则(没有 override 关键字)它可以被认为是 method overload,这不是预期的。

通常不理会 override 只是移动一个错误。我找到了更好的错误位置——在你定义无法重写的方法的地方,而不是在你实例化 class.

的地方

但是,有一种方法可以防止运行时错误。

struct Base {
  virtual void foo(int x = 0) = 0;

  void foo(double d) {
      foo( (int)d );
  }
};
inline void Base::foo(int x) { std::cout << "Default foo(" << x << ")\n"; }

struct Derived:Base {
  using Base::foo;
  virtual void foo() { // oops, no int!
    std::cout << "Derived::foo()\n";
    Base::foo();
  }
};
struct Derived2:Derived {
  virtual void foo(int x=0) override {
    std::cout << "Derived2::foo()\n";
    Derived::foo(x);
  }
};

这里我们打算让每个 foo 调用其父 foo。但是因为 Derived::foo 没有覆盖与 Base::foo 相同的签名,所以它没有被调用。

Derived 中的 foo() 之后添加 override,我们得到一个编译时错误。

是的,我实现了纯虚函数Base::foo