C++11学習3:虚関数リロード表示(override)

2207 ワード

5.虚関数の再ロードを表示する
C++では,サブクラスでは意外にも虚関数をリロードしやすい.例として、
struct Base {
    virtual void some_func();
};
 
struct Derived : Base {
    void some_func();
};
Derived::some_funcの真の意図はなぜですか.プログラマーは本当にこの虚関数を再ロードしようとしたのか、それともこれは意外なことなのか.これはまた、baseのメンテナが、Derived::some_funcと同名で同じパラメータを有する虚関数を加えた可能性もある.
 
もう1つの可能性のある状況は、ベースクラスの虚関数の名前またはパラメータが変更されると、サブクラスの古い署名を持つ関数が虚関数を再ロードしなくなることです.したがって、プログラマがすべてのサブクラスを変更することを忘れた場合、実行期間は虚関数の正しい実装に正しく呼び出されません.
C++11は、上記の状況の発生を防止し、実行期間ではなくコンパイル期間でこのようなエラーをキャプチャするためのサポートを追加します.この機能は、後方互換性を維持するために選択されます.構文は次のとおりです.
struct Base {
    virtual void some_func(float);
};
 
struct Derived : Base {
    virtual void some_func(int) override;   //     : Derive::some_func     override Base::some_func
    virtual void some_func(float) override; // OK
};

 
コンパイラは、ベースタイプに仮想関数が存在するかどうかをチェックします.派生クラスにoverrideと宣言された仮想関数と同じ関数があります.存在しない場合は、エラーが発生します.
C++11はまた、タイプが継承されたり、ベースタイプの関数が書き換えられたりすることを避けるための指示字finalを提供する.
struct Base1 final { };
 
struct Derived1 : Base1 { }; //     : class Base1      final
 
struct Base2 {
    virtual void f() final;
};
 
struct Derived2 : Base2 {
    void f(); //     : Base2::f      final
};

 
以上の例では、virtual void f() final;は新しい仮想関数を宣言し、派生関数が元の仮想関数を書き換えることを禁止することを示しています.overridefinalも言語キーワード(keyword)ではなく、特定の位置にのみ特別な意味があり、他の場所では一般指示字(identifier)として使用することができる.