名稱空間
變體
操作

final 說明符 (C++11 起)

來自 cppreference.com
< cpp‎ | 語言
 
 
C++ 語言
 
 

指定 虛擬函式 不能在派生類中被覆蓋,或一個類不能被 派生

目錄

[編輯] 語法

當應用於成員函式時,識別符號 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 起)
1) 在成員函式宣告中,final 可以出現在 virt-specifier-seq 中,緊隨宣告符之後,並且在 pure-specifier 之前(如果使用)。
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(如果使用)是 overridefinal,或者 final overrideoverride 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 序列中

  1. 其中之一是 classstructunion
  2. 一個可能是限定的 識別符號
  3. final
  4. 其中之一是 :{

序列中的第三個 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()
{
}

[編輯] 關鍵詞

final

[編輯] 示例

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)[編輯]