final修饰类时必须紧接类名后、花括号前,禁止继承;修饰虚函数时须置于声明末尾、分号前,禁止派生类覆写;非虚函数或错误位置使用均触发编译错误。

final 修饰类或虚函数,必须写在声明末尾,且仅对 class 定义和 virtual 函数有效;写错位置、用在非虚函数上、或试图继承 final 类,都会触发编译错误。
修饰类:class 名后紧跟 final,禁止任何派生
把 final 放在类名后面、花括号前,是唯一合法写法。一旦加上,所有 class Derived : public Base 形式的继承都会被编译器拒绝。
- 正确写法:
class Base final { /* ... */ }; - 错误写法:
final class Base { ... };(final不是存储类说明符,不能前置) - 错误写法:
class Base { ... } final;(语法错误,final必须紧贴类名) - 继承
final类时,GCC/Clang 报错类似:error: cannot derive from 'final' base 'Base' in derived type 'Derived'
修饰虚函数:声明末尾加 final,阻止后续覆写
只有 virtual 函数才能加 final,且必须放在函数声明的右括号之后、分号之前。它不改变当前函数行为,只封死派生链中更下游的覆盖可能。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 正确写法:
virtual void func() final;或virtual void func() const final; - 错误写法:
void func() final;(非虚函数加final→ 编译失败) - 错误写法:
virtual final void func();(final不能前置) - 若派生类仍尝试
override该函数,编译器报错类似:error: function 'func' declared 'final' cannot be overridden
常见误用:final 和 override 混搭时的位置与逻辑
override 和 final 可以共存,但顺序固定:override 在前,final 在后。这表示“我确实在覆写基类虚函数,且到此为止,不准再覆写”。
- 合法写法:
void func() override final; - 非法写法:
void func() final override;(顺序反了,编译失败) - 非法写法:
void func() final;在非虚函数上(哪怕函数签名和基类一致,也不行) - 注意:
final是针对“能否被进一步覆写”,不是针对“是否已覆写”——所以基类虚函数本身就可以带final,不需要先被某个派生类覆写过
容易被忽略的关键限制
final 的语义非常强硬,但它的生效完全依赖编译期检查,运行时无任何痕迹。这意味着:
- 它不参与 ABI 兼容性判断,加了
final可能导致二进制不兼容(尤其在动态库接口中要谨慎) - 模板类里不能直接用
final修饰整个特化,只能对具体实例化的类加(如template<typename t> class X { ... }; class X<int> final { ... };</int></typename>) - 友元关系、私有继承、using 声明都不绕过
final限制——继承就是继承,不管你怎么绕,编译器都拦 - 最易漏的一点:头文件中定义的
final类,如果被多个 TU 包含,不会引发 ODR 违规;但它一旦被标记,所有使用点都受约束,改起来牵一发而动全身
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










