yohhoyの日記

技術的メモをしていきたい日記

overrideキーワード指定の強制?

C++11で新しく導入されたoverrideキーワード*1に関するメモ。コーディング時のミスや設計変更により「意図せず正しいオーバーライドになっていない*2」事態を防ぐ仕組みだが、C++11にはこのoverrideキーワード利用自体を強制する機能はない。

overrideキーワードは、派生クラスの該当メンバ関数が「基底クラスの仮想関数をオーバーライドする」と表明するものであり、関数シグネチャ誤りなどで正しくオーバーライドにならない場合はコンパイルエラーとなる。ただしC++03との下方互換性のため、メンバ関数へのoverride指定を行わなくてもオーバーライドは可能。

struct B {
  virtual int mf(float);
};

struct D : B {
  virtual int mf(float) override;  // OK: B::mf1を正しくオーバーライド
  // virtual int mf1(float);       // OK: override指定は任意
  virtual int mf(int) override;    // NG: 関数オーバーライドでない
};

N2365では派生クラス宣言でのoverride指定を強制させるcheck_names属性が提案され、N2928でcheck_namesからbase_check属性に名前変更されたが、N3206でhidding属性とともに削除された。またN3206での “クラス宣言へのexplicitキーワード指定” が機能的にcheck_names/base_checkと同等のようだが、これもN3272にて削除された。最終的に、C++11ではクラス宣言でのfinal指定のみ可能。

関連URL

*1:C++言語における override と final はコンテキスト依存キーワード(contextual keyword)であり、メンバ関数宣言でのみ特定の意味をもつ。構文的には単なる識別子(identifier)とされており、int や class などの通常のキーワード(keyword)とは違いクラス名や変数名に用いてもよい。とはいえ、下方互換性のための措置なので新規コードでは利用を避けるべき。

*2:基底クラスメンバ関数を正しくオーバーライド出来ていない場合、C++コンパイラは「新しい別のシグネチャを持つメンバ関数を追加した」と解釈する/せざるをえない。