C ++ 11の新機能6:オーバーライドとファイナル



C 11 New Feature Six



2012年3月22日、GCC4.7.0が正式にリリースされました。このバージョンから、GCCは多くの新しいC ++ 11機能を追加しました。今日は、これらの機能の1つであるfinalキーワードとoverrideキーワードの明示的な使用を紹介します。最初に次の例を見てください。
struct B1 final { } struct D1: B1 {} // Wrong! Cannot inherit from final class! D1がB1を継承しようとしており、B1がfinalとして宣言されているため、上記のコードは間違っています。 Javaみたいですね。もちろん!他の使用法があります:
struct B2 { virtual void f() final {} // final function } struct D2 : B2 { virtual void f() {} // Error! }

D2 :: fはB2 :: fを書き換えますが、B2 :: fはfinalとして宣言されているため、このコードは再び失敗します。

仮想関数が派生クラスで書き換えられることを示す必須のメカニズムがまだないため、C ++での仮想関数の設計は非常に貧弱だと常に感じています。 vitualキーワードはオプションであるため、コードを読むのは非常に面倒です。メソッドが仮想関数であるかどうかを判断するために、継承システムのソースまでさかのぼる必要がある場合があるためです。読みやすさを向上させるために、私は常に派生クラスに仮想キーワードを記述し、すべての人にそうすることをお勧めします。それでも、微妙なエラーがいくつかあります。



別のコードを見てみましょう。

struct B3 { virtual void f() {} } struct D3 : B3 { void f() {} } D3を開発するプログラマーは本当にB3 :: f関数を書き直したいですか?または、彼は誤って親クラスと同じ名前の関数を作成したのに、誤ってそれを上書きしてしまったのでしょうか。この種のエラーを回避するために、C ++ 11ではoverrideキーワードが導入されました(C#によく似ています!)。したがって、次のコードが間違っていることがわかります。
struct B4 { virtual void g(int) {} } struct D4 : B4 { virtual void g(int) override {} // OK virtual void g(double) override {} // Error } overrideキーワードのおかげで、この見つけにくいプログラムエラーの検出をコンパイラに支援させることができます。このコードのエラーは、overrideキーワードが、g(double)が操作をオーバーライドしたいが、実際の親クラスにはそのような関数がないことを示していることです。

これらは構文上の糖衣構文ではありませんが、実際には多くのプログラムエラーを回避でき、コンパイラーがいくつかの最適化を行うことができることを示唆していることは注目に値します。上記のB2 :: fなど、finalとマークされた仮想関数を呼び出すと、GNU C ++フロントエンドはこの関数を上書きできないことを認識するため、クラスの仮想テーブルから削除されます。上記のB1のように、finalとしてマークされたクラスの場合、コンパイラは仮想テーブルをまったく生成しません。そのようなコードは明らかにより効率的です。




https://www.devbean.net/2012/05/cpp11-override-final/