final 指定子 (C++11 以降)
派生クラスでオーバーライドできない 仮想関数であることを指定するか、またはクラスから 派生できないことを指定します。
目次 |
[編集] 構文
メンバ関数に適用される場合、識別子 final は、クラス定義内のメンバ関数宣言またはメンバ関数定義の構文における 宣言子 の直後に現れます。
クラス(struct および union を含む)に適用される場合、識別子 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) | (C++26まで) | |||||||
| class-key attr (任意) class-head-name class-prop-specifier-seq (任意) base-clause (任意) | (4) | (C++26以降) | |||||||
final は宣言子の直後、pure-specifier(使用されている場合)の前に virt-specifier-seq に現れることがあります。final は宣言子の直後、function-body の直前に virt-specifier-seq に現れることがあります。final はクラス名の直後、base-clause を開始するコロンの直前に class-virt-specifier として現れることがあります(使用されている場合)。final は class-prop-specifier-seq に現れることがありますが(使用されている場合)、一度だけです。ケース (1,2) では、virt-specifier-seq は、使用されている場合、override、final、final override、または override final のいずれかです。ケース (3) では、class-virt-specifier の許可される唯一の値は final です。ケース (4) では、class-prop-specifier-seq は、使用されている場合、任意の数の クラスプロパティ指定子 (C++26 以降) を持つことができますが、それぞれが最大で 1 回しか現れません。
[編集] 説明
仮想関数宣言または定義で使用される場合、final 指定子は、その関数が仮想であることを保証し、派生クラスでオーバーライドできないことを指定します。それ以外の場合は、プログラムは不正な形式になります(コンパイル時エラーが発生します)。
クラス定義で使用される場合、final は、このクラスが別のクラス定義の base-specifier-list に現れることができない(つまり、派生できない)ことを指定します。それ以外の場合は、プログラムは不正な形式になります(コンパイル時エラーが発生します)。final は union 定義と組み合わせて使用することもできますが、その場合、効果はありません(std::is_final の結果以外) (C++14 以降)。これは、union からは派生できないためです。
final は、メンバ関数宣言またはクラスヘッダーで使用される場合に特別な意味を持つ識別子です。その他のコンテキストでは予約されておらず、オブジェクトや関数の命名に使用できます。
[編集] 注意
以下のトークンのシーケンスにおいて
class、struct、unionのいずれか- 修飾されている可能性のある 識別子
- final
:または{のいずれか
シーケンス内の 3 番目のトークン final は、常に識別子ではなく指定子として解釈されます。
struct A; struct A final {}; // OK, definition of struct A, // not value-initialization of variable final struct X { struct C { constexpr operator int() { return 5; } }; struct B final : C{}; // OK, definition of nested class B, // not declaration of a bit-field member final }; // Abnormal final usage. struct final final // OK, definition of a struct named `final` from which { // you cannot inherit }; // struct final final {}; // Error: redefinition of `struct final`, NOT a // definition of a variable `final` using an elaborated // type specifier `struct final` followed by an // aggregate initialization // struct override : final {}; // Error: cannot derive from final base type; // `override` in given context is a normal name void foo() { [[maybe_unused]] final final; // OK, declaration of a variable named `final` of type // `struct final` } struct final final; // OK, declaration of a variable named `final` of type // `struct final` using an elaborated type specifier int main() { }
[編集] キーワード
[編集] 例
struct Base { virtual void foo(); }; struct A : Base { void foo() final; // Base::foo is overridden and A::foo is the final override void bar() final; // Error: bar cannot be final as it is non-virtual }; struct B final : A // struct B is final { void foo() override; // Error: foo cannot be overridden as it is final in A }; struct C : B {}; // Error: B is final
実行結果の例
main.cpp:9:10: error: 'void A::bar()' marked 'final', but is not virtual
9 | void bar() final; // Error: bar cannot be final as it is non-virtual
| ^~~
main.cpp:14:10: error: virtual function 'virtual void B::foo()' overriding final function
14 | void foo() override; // Error: foo cannot be overridden as it is final in A
| ^~~
main.cpp:8:10: note: overridden function is 'virtual void A::foo()'
8 | void foo() final; // Base::foo is overridden and A::foo is the final override
| ^~~
main.cpp:17:8: error: cannot derive from 'final' base 'B' in derived type 'C'
17 | struct C : B // Error: B is final
|[編集] 参照
- C++23標準 (ISO/IEC 14882:2024)
- 11 Classes [class]
- 11.7.3 Virtual functions [class.virtual]
- C++20 standard (ISO/IEC 14882:2020)
- 11 Classes [class]
- 11.7.2 Virtual functions [class.virtual]
- C++17 standard (ISO/IEC 14882:2017)
- 12 Classes [class]
- 13.3 Virtual functions [class.virtual]
- C++14 standard (ISO/IEC 14882:2014)
- 9 Classes [class]
- 10.3 Virtual functions [class.virtual]
- C++11 standard (ISO/IEC 14882:2011)
- 9 Classes [class]
- 10.3 Virtual functions [class.virtual]
[編集] 不具合報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| CWG 1318 | C++11 | クラス名と 空のメンバ仕様リストの後に final を持つクラス定義は、final を識別子と見なす可能性があります。 |
final は常に この場合、指定子です。 |
[編集] 関連項目
override 指定子 (C++11) |
メソッドが別のメソッドをオーバーライドすることを明示的に宣言します |
| クラスプロパティ指定子 (C++26) | final 指定子 (C++11)、置換可能性 (C++26)、自明な移動可能性 (C++26) |