◐ Shell
clean mode source ↗

final 指定子 (C++11以上) - cppreference.com

提供: cppreference.com

仮想関数が派生クラスでオーバーライドできないこと、またはクラスが継承できないことを指定します。

構文

メンバ関数に適用されるとき、識別子 final はメンバ関数の宣言またはクラス定義の内部のメンバ関数の定義の構文の宣言子の直後に現れます。

クラスに適用されるとき、識別子 final はクラス定義の先頭、クラスの名前の直後に現れます。

declarator virt-specifier-seq(オプション) pure-specifier(オプション) (1)
declarator virt-specifier-seq(オプション) function-body (2)
class-key attr(オプション) class-head-name class-virt-specifier(オプション) base-clause(オプション) (3)

1) メンバ関数の宣言では、 final は、使用される場合は、宣言子の直後、純粋指定子の前の virt-specifier-seq に現れることができます。

2) クラス定義の内部のメンバ関数の定義では、 final は、宣言子の直後、 function-body の前の virt-specifier-seq に現れることができます。

3) クラス定義では、 final は、使用される場合は、クラスの名前の直後、 base-clause の始まりのコロンの直前の class-virt-specifier として現れることができます。

(1,2) では、 virt-specifier-seq は、使用される場合は、 override または final または final override または override final のいずれかです。 (3) では、使用される場合は、 class-virt-specifier の唯一許される値は final です。

説明

仮想関数の宣言または定義で使用されたとき、 final は、その関数が仮想であることを保証し、派生クラスによってオーバーライドされてはならないことを指定します。 そうでなければ、プログラムは ill-formed です (コンパイル時エラーが生成されます)。

クラス定義で使用されたとき、 final は、そのクラスが別のクラス定義の base-specifier-list 内に現れてはならない (別の言い方をすると、派生できない) ことを指定します。 そうでなければ、プログラムは ill-formed です (コンパイル時エラーが生成されます)。 final共用体の定義でも使用できます。 この場合、効果はありません (共用体は元々派生できないため。 ただし std::is_final の結果には反映されます)。

final はメンバ関数の宣言またはクラスの先頭で使用されたときに特別な意味を持つ識別子です。 それ以外の文脈では予約されておらず、オブジェクトや関数の名前に使用しても構いません。

struct Base
{
    virtual void foo();
};

struct A : Base
{
    void foo() final; // Base::foo をオーバーライドします。 final オーバーライドです。
    void bar() final; // エラー、 bar は仮想関数でないため final にできません。
};

struct B final : A // 構造体 B は final です。
{
    void foo() override; // エラー、 foo は A で final のためオーバーライドできません。
};

struct C : B // エラー、 B は final です。
{
};

関連項目