253

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

それですか?

4

6 に答える 6

288

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

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

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

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

于 2012-12-14T14:13:28.807 に答える
39

ウィキペディアの引用:

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

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

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

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

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

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

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

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

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

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

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

于 2012-12-14T14:09:08.637 に答える
5

はい、そうです。これは、上書きを試みて、署名の失敗によって台無しにしないようにするためのチェックです。これを詳細に説明し、簡単な例を示した Wiki ページを次に示します。

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

于 2012-12-14T14:08:46.450 に答える