web-dev-qa-db-ja.com

基本クラスを持たない(派生していない)クラスの仮想関数にfinalキーワードを追加することは意味がありますか?

私は素晴らしい 素晴らしいC++ 11チュートリアル を読んでおり、著者はfinalキーワードを説明しながらこの例を提供しています。

_struct B {
    virtual void f() const final;   // do not override
    virtual void g();
};
struct D : B {
    void f() const;     // error: D::f attempts to override final B::f
    void g();       // OK
};
_

では、ここでfinalキーワードを使用するのは理にかなっていますか?私の意見では、ここでvirtualキーワードの使用を避け、f()が上書きされないようにすることができます。

27

関数をvirtualおよびfinalとしてマークしない場合でも、子クラスは関数を実装し、基本クラス関数を非表示にすることができます。

関数をvirtualおよびfinalにすることにより、子クラスはオーバーライドできませんまたは関数を非表示にします。

32

はい!提供する例では、finalキーワードは、正しく言うように、派生クラスがf()をオーバーライドするのを防ぎます。関数が非仮想の場合、D:f()hide関数の基本クラスバージョンを許可されます。

_struct B {
    void f() const;   // do not override
    virtual void g();
};
struct D : B {
    void f() const; // OK!
    void g();       // OK
};
_

f()virtualおよびfinal関数にすることにより、オーバーライドまたは非表示にしようとすると、コンパイルエラーが発生します。

11
Karl Nicoll

あなたの直感は正しいです。関数をvirtualにして、すぐにfinalでキャップするだけでは、非仮想関数に勝る利点はありません。これは、機能を示すための短いサンプルスニペットです。

さらに、他の回答で説明されているように、これは実際には関数の非表示を壊します-fまたはその派生クラスのいずれかに同じパラメータリストを持つD関数を持つことはできません。
これは、モデルでfを制限することを決定したときに実行するトレードオフです。ここでは実際の仮想通話を実行する方法がないため、基本的に欠点があり、利点はありません。

2
Quentin