仮想関数は最初からC++に存在し、動的ポリモーフィズムの手段として使用されていました。しかし、以前は派生クラスにおける仮想関数のオーバーライドの正当性をコンパイラがチェックさせる構文メカニズムは存在していませんでした。C++11の登場以降、キーワードoverrideは追加のコンパイラチェックのツールとなりました。
overrideがなければ、コンパイラは関数が実際に基底クラスのメソッドをオーバーライドしていることを保証しません。シグネチャにおける誤り(例えば、不正な型やconst)は、新しい関数を派生クラスに作成してしまい(「隠蔽」)、ポリモーフィズムが破壊され、デバッグが難しくなります。
派生クラスで仮想関数を宣言する際にoverrideを使用することで、コンパイラはシグネチャが親の仮想関数と正確に一致していることを確認し、関数が実際に親をオーバーライドしているかどうかを検証します。そうでない場合、コンパイルはエラーで中断されます。
コード例:
struct Base { virtual void foo() const {} }; struct Derived : Base { void foo() const override { /* 実装 */ } };
もしDerivedにvoid foo()と書いた場合、const overrideなしで、コンパイラはエラーを出力します。
主な特徴:
キーワード「override」を使用して仮想関数を残すことはできますが、「virtual」キーワードなしで行うことはできますか?
はい、overrideは関数が仮想であることを暗示しています。overrideと一緒にvirtualを指定することは冗長ですが、禁止されてはいません。
関数がconstまたはref修飾子(例えば、&または&&)のみで異なる場合、エラーは発生しますか?
はい、シグネチャの違いはconst/referencesを含め、オーバーライドを破ってしまいます。例えば、void foo() overrideはvoid foo() constをオーバーライドせず、コンパイラはoverrideによってそれを検出します。
「override」を静的関数やコンストラクタに適用できますか?
いいえ。overrideは仮想関数専用であり、静的関数、コンストラクタ、デストラクタ(仮想でない場合)には適用できません。
大規模プロジェクトで、派生クラスに関数のシグネチャにタイプミスがあり、関数は実際にはオーバーライドされておらず、開発者は逆に考えてしまい、ポリモーフィズムが期待通りに機能しません。
利点:
欠点:
すべての派生クラスでoverrideが使用されており、テストがビルド時にエラーを捕捉します。
利点:
欠点: