例えば:
_class Base {
virtual void my_function() = 0;
};
class Derived : Base {
void my_function() override;
};
_
私が読んだものから、override
キーワードを使用して、オーバーライドする関数に正しい署名があることを確認し、それが唯一の使用であるようです。
ただし、純粋仮想関数の場合、Derivedクラス(または物事の見方によってはBaseクラス)で間違った署名を使用すると、コンパイラはエラーをスローします。それで、Derived::my_function()
宣言の最後にoverride
を追加する点はありますか?
ただし、純粋な仮想関数の場合、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
の定義をより明確/読みやすくするときにのみ発生します。
はい、守備の慣行としてoverride
キーワードを一貫して使用することをお勧めします。
Base
の作成者がmy_function
はもはや純粋な仮想であってはならず、また新しいパラメーターをとるべきです。 override
を配置すると、コンパイラはこの問題をキャッチします。 override
なしでは、Derived
クラスは引き続きコンパイルされます。
はい !!
コードの明瞭性が向上します:override
キーワードは曖昧さを防ぎ、その基本クラスメソッドをオーバーライドする意味を伝えます。
意図しない使用の可能性を防ぐ:将来、ベースクラスがメソッドシグニチャーを変更した場合(ここでvirtual
)、派生クラスを強制的に変更します。 (コンパイラエラーあり)。それ以外の場合(override
キーワードなしで)method overload
、これは意図されていません。
通常、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
_と同じ署名をオーバーライドしないため、呼び出されません。
override
のfoo()
の後にDerived
を追加すると、コンパイル時エラーが発生します。
そして、はい、純粋仮想関数_Base::foo
_を実装しました。