final关键字用于禁止类被继承或虚函数被重写,是编译期强制约束;类名后加final禁止继承,虚函数声明末尾加final禁止重写,仅适用于虚函数且不可用于定义、非虚函数或构造/析构函数。

final 关键字在 C++11 中引入,作用很明确:禁止类被继承,或禁止虚函数被重写。它不是修饰符“开关”,而是编译期强制约束,写错会直接报错。
用 final 禁止类被继承
在类名后加 final,该类不可作为基类:
class Base final {
public:
virtual void func() {}
};此时若尝试继承:
class Derived : public Base {}; // 编译错误:cannot derive from 'final' class- 必须紧贴类定义末尾,不能放在访问说明符后(如
public final class Base是非法的) - 模板类也可用
final,但实例化后才检查是否被继承(即派生类模板实例化时才报错) - 与
delete构造函数不同:final阻止的是继承关系本身,不阻止对象创建
用 final 禁止虚函数被重写
在虚函数声明末尾加 final,子类中同签名函数将无法重写:
立即学习“C++免费学习笔记(深入)”;
class Base {
public:
virtual void func() final {} // 注意:final 在函数声明末尾
};子类中试图覆盖会失败:
class Derived : public Base {
public:
void func() override {} // 编译错误:function marked 'final' cannot be overridden
};-
final只能用于虚函数(含纯虚函数),对非虚函数加final是语法错误 -
override和final可同时出现,顺序不限,但final必须在声明结尾(virtual void f() override final;合法) - 如果父类函数是
final,子类中即使不写override,只要函数签名匹配,也会触发错误
final 的常见误用和陷阱
它不提供运行时保护,也不影响对象布局或性能 —— 完全是编译器语义检查工具。
- 不能用于普通成员函数、静态函数、友元函数或构造/析构函数(除非是虚析构函数)
- 不能用于函数定义(仅声明),如下写法错误:
virtual void func() final { /* ... */ } // 声明处可,定义处不可 - 头文件中使用
final会影响 ABI:一旦加了final,后续版本若想取消继承限制,必须移除final并重新编译所有依赖代码 - 和
sealed(C++/CLI)或 Java 的final行为相似,但 C++ 中无运行时等价机制
真正容易被忽略的是:当你在大型继承体系中给某个中间类加 final,可能破坏下游模块的扩展能力,而错误只在第三方派生时才暴露 —— 所以 final 更适合用于明确设计为“终端”的类型,比如 std::string_view 这类轻量值类型,而非通用基类。











