override关键字仅捕获未重写基类虚函数的编译期错误:非虚函数、签名不匹配(参数/const/返回类型协变)、函数名拼写错误;不检查访问权限,且需置于声明末尾,不可与virtual共用。

override 关键字能捕获哪些编译期错误?
它只做一件事:强制检查当前函数是否**恰好重写了基类的虚函数**。不是虚函数、签名不一致(参数类型/const 修饰/返回类型协变违规)、拼错函数名——统统报错。
常见错误现象:error: 'func' does not override a base class member 或 error: method 'func' was declared 'override' but does not override any base class methods。
- 基类函数没加
virtual,子类却用override→ 编译失败 - 子类参数写成
int x,基类是const int& x→ 不匹配,override拦住 - 子类漏掉
const(基类是virtual void get() const,子类写void get())→ 不视为重写,触发报错 - 返回类型不满足协变规则(比如基类返回
Base*,子类返回Derived&)→ 编译拒绝
不写 override 会怎样?典型静默陷阱
没有 override,编译器不会校验“你是不是真想重写”。它可能默默把你当成一个全新函数——名字碰巧一样,但多态失效。
使用场景:重构基类接口时最危险。比如把 virtual void process() 改成 virtual void process(int flag),所有没加 override 的子类实现依然编译通过,但运行时永远调不到它们——调用的是基类空实现或默认行为,bug 往往延迟暴露。
立即学习“C++免费学习笔记(深入)”;
- 子类函数签名和基类不一致 → 编译通过,但失去多态性,
ptr->process()调的是基类版本 - 基类删掉某个虚函数,子类残留同名函数 → 编译通过,变成孤立函数,完全不参与虚表
- 拼错函数名(
procss())→ 零提示,逻辑彻底断开
override 和 virtual 一起用还是只用 override?
子类中必须写 override,**不能只写 virtual**。写了 virtual 但没 override,就退回到老式模糊语义;写了 override 就自动隐含了虚函数身份,无需再加 virtual。
参数差异:C++11 起 override 是说明符(specifier),不是修饰符(qualifier),语法位置在函数声明末尾,紧挨着 const/& 等限定符之后。
- ✅ 正确:
void draw() const override; - ❌ 错误:
virtual void draw() const override;(重复冗余,部分编译器警告) - ❌ 错误:
override void draw() const;(语法错,override必须在末尾)
性能无影响——它纯属编译期检查,不生成额外代码,也不改变虚表布局。
继承链深、模板基类时 override 容易失效吗?
会。尤其是基类是模板类(如 template<typename t> struct Base { virtual void foo(); }</typename>),子类特化后若未显式从该特化实例继承,或 using 声明未正确带出虚函数,override 可能找不到目标。
兼容性影响:C++11 起支持,旧项目若需兼容 C++98,不能用;但只要用现代标准,就该默认开启——Clang/GCC/MSVC 全支持,且 -Woverloaded-virtual 等警告无法替代 override 的精确性。
- 模板基类中虚函数未在子类继承路径上“可见” →
override报错,需检查using Base<t>::foo;</t>或继承方式 - 多重继承中同名虚函数来自多个基类 →
override要求明确匹配其中一个,否则报错 - 父类虚函数被
final修饰 → 子类用override会触发error: cannot override a function marked 'final'
真正容易被忽略的是:override 不检查访问权限。基类是 protected virtual,子类用 public 重写并加 override,完全合法——但调用侧若越权访问,那是另一层问题。








