final 指定符 (C++11 起)

来自cppreference.com
< cpp‎ | language

指定虚函数不能被导出类覆写,或类不能被继承

目录

[编辑] 语法

应用到成员函数时,标识符 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)
1) 在成员函数声明中, final 可以出现于立即在声明器后的 virt-specifier-seq ,且在 pure-specifier 前,若使用它。
2) 在类定义内的成员函数定义中, final 可以出现于立即在声明器后的 virt-specifier-seq 且正好在 function-body 前。
3) 在类定义中, final 可以出现作立即在类名后,正好在起始 base-clause (若使用它)的冒号前作为 class-virt-specifier

情况 (1,2) 中,若使用 virt-specifier-seq ,则它是 overridefinalfinal overrideoverride final 之一。情况 (3) 中, class-virt-specifier 仅有的被允许值是 final ,若使用它。

[编辑] 解释

在虚函数声明或定义中使用时, final 确保函数为虚且不可被导出类覆写。若这么做则程序为病态(生成编译时错误)。

在类定义中使用时, final 指定此类不可出现于另一类的定义的 base-specifier-list 中(换言之,它不能导出)。若这么做则程序为病态(生成编译时错误)。 final 亦可用于联合体定义,此情况下它无效(除了 std::is_final 上的结果),因为联合体不能派生

final 是在用于成员函数声明或类头部时有特殊含义的标识符。其他语境中它非保留而且可用于命名对象或函数。

[编辑] 示例

struct Base
{
    virtual void foo();
};
 
struct A : Base
{
    void foo() final; // A::foo 被覆写且是最终覆写
    void bar() final; // 错误:非虚函数不能被覆写或是 final
};
 
struct B final : A // struct B 为 final
{
    void foo() override; // 错误: foo 不能被覆写,因为它在 A 中是 final
};
 
struct C : B // 错误: B 为 final
{
};

[编辑] 参阅