override关键字只检查当前函数是否恰好覆盖基类中的虚函数,要求参数类型、const修饰、引用限定符、返回类型(协变除外)完全匹配。

override 关键字到底检查什么
它只检查:当前函数是否**恰好覆盖了基类中一个虚函数**——不多不少,参数类型、const 修饰、引用限定符、返回类型(协变除外)都得对得上。不是“只要名字一样就行”,也不是“只要能多态调用就通过”。
常见错误现象:error: 'func' does not override any member functions,往往是因为拼写差一个字母、const 少写了、参数是 int 但基类是 int&,或者基类函数根本没加 virtual。
使用场景:所有你明确想覆盖虚函数的地方,尤其是继承链变深、接口变更频繁时。不加 override,改错基类签名可能让派生类函数悄悄变成新函数,静默失效。
什么时候必须写 override 才能编译通过
不是“必须写”,而是“写了就强制校验”。但以下情况不加 override 很容易埋雷:
立即学习“C++免费学习笔记(深入)”;
- 基类虚函数加了
const,而你重写的版本漏了 —— 不加override编译器默认当新函数,运行时调不到 - 基类函数签名从
void f(int)改成void f(long),你的派生类仍留着f(int)—— 不加override不报错,但已失去覆盖关系 - 基类函数返回类型是基类指针,你返回派生类指针(协变),但忘了加
override—— 虽然合法,但失去编译期保障
override 和 virtual 能不能一起写
可以,而且推荐一起写。基类函数必须有 virtual,派生类覆盖时加 override 是独立语法,二者不冲突。
示例:
struct Base {
virtual void draw() const;
};
struct Derived : Base {
void draw() const override; // ✅ 正确:既有 virtual(继承而来),又有 override 显式声明
};
注意:override 只能用于成员函数声明(在类内),不能用于定义(类外实现)。下面这样是错的:
void Derived::draw() const override { ... } → 编译报错:error: 'override' cannot be used here
兼容性与编译器支持差异
override 是 C++11 引入的关键字,所有现代编译器都支持,但要注意:
- VS2012+、GCC 4.7+、Clang 3.3+ 完全支持
- 如果项目还需兼容 C++98/03,不能用
override;但这种场景现在极少见 - 某些旧版 IDE(如老版本 VS Code + C++ 插件)可能语法高亮异常,不影响编译,别被误报干扰
- 宏定义里别碰
override—— 它是关键字,不是标识符,#define override final这种 hack 会破坏语义且不可移植
最容易被忽略的一点:它不检查函数是否真的被调用,也不保证虚表布局正确;它只做签名匹配。虚函数调用是否生效,还得看对象实际类型和指针/引用的静态类型——这点和 override 本身无关,但很多人混淆。










