Namespaces
Variants

final specifier (since C++11)

From zh.cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Virtual function
override specifier (C++11)
final specifier (C++11)
Special member functions
Templates
Miscellaneous

指定一个 虚函数 不能在派生类中被重写,或者某个类不能被 继承 。

目录

语法

当应用于成员函数时,标识符 final 在类定义中的成员函数声明或成员函数定义语法里,紧跟在 声明符 之后出现。

当应用于类(包括结构体和联合体)时,标识符 final 出现在类定义的开头,紧跟在类名之后,且不能在类声明中出现。

声明符 虚说明符序列  (可选) 纯说明符  (可选) (1)
声明符 虚说明符序列  (可选) 函数体 (2)
类关键字 属性  (可选) 类头名称 类虚说明符  (可选) 基类子句  (可选) (3) (C++26 前)
类关键字 属性  (可选) 类头名称 类属性说明符序列  (可选) 基类子句  (可选) (4) (C++26 起)
1) 在成员函数声明中, final 可出现在声明符之后的 virt-specifier-seq 中,且若使用 pure-specifier 则位于其之前。
2) 在类定义内部的成员函数定义中, final 可以出现在声明符之后、 函数体 之前的 虚说明符序列 中。
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 指定该类不能出现在其他类定义的 基类说明符列表 中(即不能被继承)。否则程序非良构(将产生编译时错误)。 final 也可用于 联合体 定义,此时该限定符没有实际作用 (仅影响 std::is_final 的判定结果) (C++14 起) ,因为联合体本身不能被继承。

final 是一个在成员函数声明或类头部使用时具有特殊含义的标识符。在其他上下文中,它不被保留,可用于命名对象和函数。

注意

在以下标记序列中:

  1. class 、 struct 和 union 其中之一
  2. 可能带有限定符的 标识符
  3. final
  4. : 或 { 其中之一

序列中的第三个标记 final 始终被视为说明符而非标识符。

struct A;
struct A final {}; // 正确:结构体 A 的定义,
                   // 不是变量 final 的值初始化
struct X
{
    struct C { constexpr operator int() { return 5; } };
    struct B final : C{}; // 正确:嵌套类 B 的定义,
                          // 不是位域成员 final 的声明
};
// 异常的 final 用法
struct final final // 正确:定义了一个名为 `final` 的结构体,
{                  // 无法从其继承
};
// struct final final {}; // 错误:`struct final` 重定义,不是
                          // 使用详细类型说明符 `struct final` 后接聚合初始化
                          // 来定义变量 `final`
// struct override : final {}; // 错误:无法从 final 基类派生;
                               // 在此上下文中 `override` 是普通名称
void foo()
{
    [[maybe_unused]]
    final final; // 正确:声明一个名为 `final` 的变量,类型为
                 // `struct final`
}
struct final final; // 正确:使用详细类型说明符声明一个名为 `final` 的变量,
                    // 类型为 `struct final`
int main()
{
}

关键词

final

示例

struct Base
{
    virtual void foo();
};
struct A : Base
{
    void foo() final; // Base::foo 被重写,A::foo 成为最终重写版本
    void bar() final; // 错误:bar 不能声明为 final,因为它非虚函数
};
struct B final : A // struct B 被声明为 final
{
    void foo() override; // 错误:foo 不可重写,因为它在 A 中已声明为 final
};
struct C : B {}; // 错误:B 是 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)