final
說明符 (C++11 起)
來自 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) | (直到 C++26) | |||||||
class-key attr (可選) class-head-name class-prop-specifier-seq (可選) base-clause (可選) | (4) | (C++26 起) | |||||||
2) 在類定義內部的成員函式定義中,
final
可以出現在 virt-specifier-seq 中,緊隨宣告符之後,並且在 function-body 之前。3) 在類定義中,
final
可以作為 class-virt-specifier 出現在類名之後,緊接在開始 base-clause 的冒號之前(如果使用)。4) 在類定義中,
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 起),但每個最多隻能出現一次。
[編輯] 解釋
當用於虛擬函式宣告或定義時,final 說明符確保該函式是虛擬函式,並指定它不能被派生類覆蓋。否則程式格式錯誤(會生成編譯時錯誤)。
當用於類定義時,final 指定此類不能出現在另一個類定義的 base-specifier-list 中(換句話說,不能被派生)。否則程式格式錯誤(會生成編譯時錯誤)。final 也可以與 union 定義一起使用,在這種情況下它沒有效果(除了對 std::is_final 的結果有影響)(C++14 起),因為聯合體不能被派生。
final 是一個識別符號,當用於成員函式宣告或類頭時具有特殊含義。在其他上下文中,它不是保留字,可以用於命名物件和函式。
[編輯] 注
在以下 token 序列中
- 其中之一是 class、struct 和 union
- 一個可能是限定的 識別符號
- final
- 其中之一是 : 和 {
序列中的第三個 token 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 類 [class]
- 11.7.3 虛擬函式 [class.virtual]
- C++20 標準 (ISO/IEC 14882:2020)
- 11 類 [class]
- 11.7.2 虛擬函式 [class.virtual]
- C++17 標準 (ISO/IEC 14882:2017)
- 12 類 [class]
- 13.3 虛擬函式 [class.virtual]
- C++14 標準 (ISO/IEC 14882:2014)
- 9 類 [class]
- 10.3 虛擬函式 [class.virtual]
- C++11 標準 (ISO/IEC 14882:2011)
- 9 類 [class]
- 10.3 虛擬函式 [class.virtual]
[編輯] 缺陷報告
下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。
缺陷報告 | 應用於 | 釋出時的行為 | 正確的行為 |
---|---|---|---|
CWG 1318 | C++11 | 一個類定義,在類名後有 final,並且 空的成員說明符列表可能會使 final 成為一個識別符號 |
final 總是 在這種情況下是說明符 |
[編輯] 參閱
override 說明符 (C++11) |
顯式宣告一個方法覆蓋另一個方法 |
類屬性說明符 (C++26) | final 說明符 (C++11), 可替換性 (C++26), 平凡可重定位性 (C++26) |