override强制编译器验证函数是否真正重写基类虚函数,签名不匹配(如缺const、参数类型差异、引用限定符不一致、返回类型不协变)即报错,避免静默隐藏导致多态失效。

override 让编译器帮你揪出“假重写”
它不改变运行行为,只强制编译器验证:你写的函数是否真的重写了基类的虚函数。一旦签名不匹配(比如少个 const、参数类型差一个引用、返回类型不协变),g++ 或 clang++ 会直接报错,而不是静默接受为新函数。
哪些地方不加 override 就容易出问题
常见错误现象:Derived::draw() 没被调用,但基类版本照常执行;或者 error: 'process' does not override a base class member 突然出现——说明你之前一直没重写成功,只是定义了个同名函数。
- 基类是
virtual void draw() const,子类写成void draw()并加override→ 编译失败(最常踩的坑) - 基类函数名拼错,比如
updata(),子类写update() override→ 编译失败 - 基类虚函数带
&引用限定符,子类漏掉 → 不匹配,override拒绝编译 - 基类函数不是
virtual(哪怕有同名非虚函数),子类加override→ 直接报错
override 的使用边界很明确
它只在派生类中、虚函数重写场景下有效,其他地方加了就是语法错误。
- 不能用于非虚函数、静态成员函数、构造/析构函数
- 基类对应函数必须声明为
virtual(或来自override链上游) - 纯虚函数也支持
override,比如virtual void init() = 0;→ 子类实现时写void init() override - C++11 起才支持;若项目仍用
-std=c++98编译,override会被当作变量名报错
和 final 搭配用能锁死继承链
当某个派生类的实现已是最终版,不希望下游再改逻辑,就用 override final:
class FinalHandler : public Base {
public:
void handle() override final {
// 这个函数既重写了 Base::handle,又禁止任何进一步重写
}
};
注意:final 必须放在 override 后面,顺序不能反;而且一旦加了 final,后续派生类再尝试重写该函数,编译器会明确提示 “cannot override final function”。
最容易被忽略的是引用限定符(& 和 &&)和 const/volatile 修饰符的严格匹配——它们属于函数签名的一部分,差一个就不是重写,override 会立刻拒绝。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











