命名空间
变体
操作

final 说明符 (since C++11)

来自 cppreference.cn
< cpp‎ | language
 
 
C++ 语言
通用主题
流程控制
条件执行语句
if
迭代语句 (循环)
for
范围 for (C++11)
跳转语句
函数
函数声明
Lambda 函数表达式
inline 说明符
动态异常规范 (在 C++17 中弃用*)
noexcept 说明符 (C++11)
异常
命名空间
类型
说明符
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
存储期说明符
初始化
 
 

指定 虚函数 不能在派生类中被重写,或者类不能被 派生

目录

[编辑] 语法

当应用于成员函数时,标识符 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 也可以与 联合体 定义一起使用,在这种情况下它没有效果(除了对 std::is_final 的结果产生影响外)(自 C++14 起),因为联合体不能被继承。

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

[编辑] 注意

在以下标记序列中

  1. 之一 class, structunion
  2. 一个可能限定的 标识符
  3. final
  4. 之一 :{

序列中的第三个标记 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++ 标准。

DR 应用于 已发布行为 正确行为
CWG 1318 C++11 类定义在类名后有 final 并且一个
空的成员规范列表可能使 final 成为标识符
final 始终是
这种情况下的说明符

[编辑] 参见

override 说明符 (C++11) 显式声明方法覆盖另一个方法[编辑]
类属性说明符 (C++26) final 说明符 (C++11), 可替换性 (C++26), 平凡可重定位性 (C++26)[编辑]