Namespaces
Variants

final specifier (since C++11)

From 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)