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