'override'キーワードは、オーバーライドされた仮想メソッドをチェックするだけですか?


226

私が理解している限りoverride、C ++ 11 でのキーワードの導入は、実装されている関数が基本クラスの関数のoverrideingであることを確認するためのチェックに過ぎませんvirtual

それですか?


50
Yes.⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣
R.マルティーニ・フェルナンデス

13
ただし、ダブルチェックではありません。これが唯一のチェックです。
Nikos C.

13
ねえ、オーバーライドはキーワードではありません。一種の文法上の砂糖です。int override = 42; // OK
KAlO2 2014年

2
さらに、宣言された関数がオーバーライドされることを説明する読みやすさが向上します;)
mots_g

5
だから、ええと... C ++ 11は、私の地元の4年間でこのようなことを教えるのに十分な標準になるのはいつですか?彼らはいつ知っていますか?
シンチ

回答:


263

それは確かにアイデアです。ポイントは、あなたが何を意味しているのかを明示しているので、さもなければサイレントエラーを診断することができます:

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

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

上記のコードはコンパイルされますが、意図したものとは異なります(がないことに注意してくださいconst)。代わりにと言った場合virtual int foo() override、関数が実際には何もオーバーライドしていないというコンパイラエラーが発生します。


74
+1:残念ながら、新しいoverride機能がこれを「修正」すると人々が提案するとき、それは少し赤いニシンです。あなたが書くために覚えているはずと同じように、それを使用するために覚えているconst);
軌道上での明度レースを

explicitクラス定義がC ++ 11に組み込まれていないことに気づきました。ええと。
aschepler 2013

1
@ascheplerそして、explicitクラス定義は何をしますか?それについてまったく聞いたことがない。
Christian Rau 2013

18
@LightnessRacesinOrbit:はい、それは間違いのない証拠ではありません。しかし、(狂ったように書き込みの一般的なルールを覚えるoverride1はそれを行うためにしようとするときは)可能性が高い覚えるコーナーケースが存在しないようにだけ凹凸が、異なるプロトタイプの機能をコピーするには普遍性がありませんIE以外であるconstか、書き込みcharの代わりintなど、
legends2k

1
@Light、指定子の最良の使用例がこの回答override言及されています。これは即時よりも未来的です。答えはoverridevirtualメソッドでを維持することを示唆しています。将来、誤って署名を変更すると、その有用性が
発揮さ

35

ウィキペディアの引用:

オーバーライド特殊識別子は、コンパイラが基本クラスをチェックして、この正確なシグネチャを持つ仮想関数があるかどうかを確認することを意味します。ない場合、コンパイラはエラーになります。

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

編集(少し答えを改善しようとする):

メソッドを「オーバーライド」として宣言することは、そのメソッド基本クラスの(仮想)メソッドを書き換えること意図していることを意味します。オーバーライドするメソッドは、書き換えるつもりのメソッドと同じ署名(少なくとも入力パラメーターに対して)を持っている必要があります。

なぜこれが必要なのですか?よく、次の2つの一般的なエラーのケースが防止されます。

  1. 新しいメソッドでタイプを誤って入力した。コンパイラーは、前のメソッドを作成しようとしていることを認識せずに、新しいメソッドとしてクラスに追加するだけです。問題は、古いメソッドがまだ存在し、新しいメソッドがオーバーロードとして追加されることです。この場合、古いメソッドに対するすべての呼び出しは、動作を変更することなく、以前と同じように機能します(これは、書き換えの本来の目的でした)。

  2. スーパークラスでメソッドを「仮想」として宣言するのを忘れていますが、それでもサブクラスでメソッドを書き直そうとします。これは明らかに受け入れられますが、動作は意図したとおりではありません。メソッドは仮想ではないため、スーパークラスへのポインターを介したアクセスは、新しい(サブクラス ')メソッドではなく古い(スーパークラス')メソッドの呼び出しを終了します。

「オーバーライド」を追加すると、明確にこれが明確になります。これにより、3つのことが期待されていることがコンパイラに通知されます。

  1. スーパークラスに同じ名前のメソッドがあります
  2. スーパークラスのこのメソッドは「仮想」として宣言されています(つまり、書き換えが意図されています)
  3. スーパークラスのメソッドは、サブクラスのメソッド(書き換えメソッド)と同じ(input *)シグネチャを持っています

これらのいずれかが偽の場合、エラーが通知されます。

*注:出力パラメーターは異なる場合がありますが、関連するタイプです。興味があれば、共変変換と反変変換について読んでください。


31

オプションのパラメーターの追加など、基本クラスの仮想メソッドシグネチャを更新したが、派生クラスのメソッドシグネチャを更新し忘れた場合に、「オーバーライド」が見つかりました。その場合、基本クラスと派生クラスの間のメソッドは多相関係ではなくなります。オーバーライド宣言がないと、この種のバグを見つけるのは困難です。


1
+1。はそのoverrideような問題を発見するための優れた方法ですが、優れた単体テストカバレッジも役立つはずです。
2017年

1
それがまさに、この新しい指定子にとても興奮している理由です。唯一の問題は、基本クラスの変更によって引き起こされるエラーを防ぐために、この機能をすでに適用している必要があることです。;-)
ウルフ


2

C ++ 17標準ドラフト

C ++ 17 N4659標準ドラフトのすべてのoverrideヒットを調べた後、識別子を見つけることができる唯一の参照は次のとおりです。override

5仮想関数がvirt-specifierオーバーライドでマークされていて、基本クラスのメンバー関数をオーバーライドしていない場合、プログラムは不正な形式です。[例:

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
}

—最後の例]

ですから、おそらく間違ったプログラムを爆破することが唯一の影響だと思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.