私が理解している限りoverride
、C ++ 11 でのキーワードの導入は、実装されている関数が基本クラスの関数のoverride
ingであることを確認するためのチェックに過ぎませんvirtual
。
それですか?
私が理解している限りoverride
、C ++ 11 でのキーワードの導入は、実装されている関数が基本クラスの関数のoverride
ingであることを確認するためのチェックに過ぎませんvirtual
。
それですか?
回答:
それは確かにアイデアです。ポイントは、あなたが何を意味しているのかを明示しているので、さもなければサイレントエラーを診断することができます:
struct Base
{
virtual int foo() const;
};
struct Derived : Base
{
virtual int foo() // whoops!
{
// ...
}
};
上記のコードはコンパイルされますが、意図したものとは異なります(がないことに注意してくださいconst
)。代わりにと言った場合virtual int foo() override
、関数が実際には何もオーバーライドしていないというコンパイラエラーが発生します。
override
機能がこれを「修正」すると人々が提案するとき、それは少し赤いニシンです。あなたが書くために覚えているはずと同じように、それを使用するために覚えているconst
);
explicit
クラス定義がC ++ 11に組み込まれていないことに気づきました。ええと。
explicit
クラス定義は何をしますか?それについてまったく聞いたことがない。
override
1はそれを行うためにしようとするときは)可能性が高い覚えるコーナーケースが存在しないようにだけ凹凸が、異なるプロトタイプの機能をコピーするには普遍性がありませんIE以外であるconst
か、書き込みchar
の代わりint
など、
ウィキペディアの引用:
オーバーライド特殊識別子は、コンパイラが基本クラスをチェックして、この正確なシグネチャを持つ仮想関数があるかどうかを確認することを意味します。ない場合、コンパイラはエラーになります。
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final
編集(少し答えを改善しようとする):
メソッドを「オーバーライド」として宣言することは、そのメソッドが基本クラスの(仮想)メソッドを書き換えることを意図していることを意味します。オーバーライドするメソッドは、書き換えるつもりのメソッドと同じ署名(少なくとも入力パラメーターに対して)を持っている必要があります。
なぜこれが必要なのですか?よく、次の2つの一般的なエラーのケースが防止されます。
新しいメソッドでタイプを誤って入力した。コンパイラーは、前のメソッドを作成しようとしていることを認識せずに、新しいメソッドとしてクラスに追加するだけです。問題は、古いメソッドがまだ存在し、新しいメソッドがオーバーロードとして追加されることです。この場合、古いメソッドに対するすべての呼び出しは、動作を変更することなく、以前と同じように機能します(これは、書き換えの本来の目的でした)。
スーパークラスでメソッドを「仮想」として宣言するのを忘れていますが、それでもサブクラスでメソッドを書き直そうとします。これは明らかに受け入れられますが、動作は意図したとおりではありません。メソッドは仮想ではないため、スーパークラスへのポインターを介したアクセスは、新しい(サブクラス ')メソッドではなく古い(スーパークラス')メソッドの呼び出しを終了します。
「オーバーライド」を追加すると、明確にこれが明確になります。これにより、3つのことが期待されていることがコンパイラに通知されます。
これらのいずれかが偽の場合、エラーが通知されます。
*注:出力パラメーターは異なる場合がありますが、関連するタイプです。興味があれば、共変変換と反変変換について読んでください。
オプションのパラメーターの追加など、基本クラスの仮想メソッドシグネチャを更新したが、派生クラスのメソッドシグネチャを更新し忘れた場合に、「オーバーライド」が見つかりました。その場合、基本クラスと派生クラスの間のメソッドは多相関係ではなくなります。オーバーライド宣言がないと、この種のバグを見つけるのは困難です。
override
ような問題を発見するための優れた方法ですが、優れた単体テストカバレッジも役立つはずです。
はい、そうです。これは、オーバーライドを試行せず、誤ったシグネチャを介してそれを台無しにしないようにするためのチェックです。これを詳細に説明し、短い例示的な例があるWikiページを次に示します。
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final
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 }
—最後の例]
ですから、おそらく間違ったプログラムを爆破することが唯一の影響だと思います。