web-dev-qa-db-ja.com

純粋な仮想関数をオーバーライドするときに「オーバーライド」を使用する点はありますか?

例えば:

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

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

私が読んだものから、overrideキーワードを使用して、オーバーライドする関数に正しい署名があることを確認し、それが唯一の使用であるようです。

ただし、純粋仮想関数の場合、Derivedクラス(または物事の見方によってはBaseクラス)で間違った署名を使用すると、コンパイラはエラーをスローします。それで、Derived::my_function()宣言の最後にoverrideを追加する点はありますか?

43
R2B2

ただし、純粋な仮想関数の場合、Derivedクラスで不適切な署名を使用すると、コンパイラはエラーをスローします

いいえ、これはコンパイルします:

_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;
};
_

エラー:void Derived::my_function(int)overrideとマークされていますが、オーバーライドしません


あなたが話しているエラーは、Derived-overrideをインスタンス化することで、間違いをより早くキャッ​​チし、Derivedの定義をより明確/読みやすくするときにのみ発生します。

72
Vittorio Romeo

はい、守備の慣行としてoverrideキーワードを一貫して使用することをお勧めします。

Baseの作成者がmy_functionはもはや純粋な仮想であってはならず、また新しいパラメーターをとるべきです。 overrideを配置すると、コンパイラはこの問題をキャッチします。 overrideなしでは、Derivedクラスは引き続きコンパイルされます。

31
dasblinkenlight

はい !!

コードの明瞭性が向上しますoverrideキーワードは曖昧さを防ぎ、その基本クラスメソッドをオーバーライドする意味を伝えます。

意図しない使用の可能性を防ぐ:将来、ベースクラスがメソッドシグニチャーを変更した場合(ここでvirtual)、派生クラスを強制的に変更します。 (コンパイラエラーあり)。それ以外の場合(overrideキーワードなしで)method overload、これは意図されていません。

7
JharPaat

通常、overrideに悩まされないだけで、エラーが発生します。エラーが発生しやすい場所を見つける-クラスをインスタンス化するときではなく、オーバーライドに失敗したメソッドを定義する場所。

しかし、これには実行時のバグから保護する方法があります。

_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_と同じ署名をオーバーライドしないため、呼び出されません。

overridefoo()の後にDerivedを追加すると、コンパイル時エラーが発生します。

そして、はい、純粋仮想関数_Base::foo_を実装しました。