override 关键字强制检查函数名、参数、const/volatile、引用限定符四项匹配,任一不满足即编译报错,防止意外定义新函数而非重写;它只能位于声明末尾、const/&/&&之前,类外定义时省略;不可用于非虚、静态、final或返回类型不协变的函数;无需与virtual共用。

不加 override 也能编译通过,但大概率不是你想要的行为——它可能根本没重写基类虚函数,只是悄悄定义了一个新函数。
为什么 override 能立刻暴露拼写或签名错误
常见错误现象:派生类写了 doWork(),但基类实际是 do_work() 或 doWork(int);或者基类函数带 const,派生类漏掉了。没有 override 时,编译器默认接受这个“新函数”,运行时调用的还是基类版本,多态失效,bug 难定位。
加上 override 后,编译器强制检查四项匹配:函数名、参数类型与个数、const / volatile 限定符、引用限定符(& / &&)。任一不满足,直接报错,比如:
error: 'foo(double)' marked 'override', but does not override any member functions
- 错误示例:
void foo(double) override→ 基类只有virtual void foo(int) - 错误示例:
void doWork() override→ 基类是virtual void doWork() const - 正确写法必须是:
void doWork() const override
override 的位置和语法细节
它不是修饰符,不能放在返回类型前,也不能省略在类内声明里——只允许出现在成员函数声明末尾、在 const / & / = 0 之前。
- 合法:
void draw() const override、virtual void update() && override - 非法:
override void draw()、void draw() override const(顺序错)、void draw() override = 0(= 0必须在override后) - 类外定义时不用写:
void Derived::draw() const { ... }——override只属于声明
哪些情况用了 override 反而会编译失败
这不是使用姿势问题,而是代码逻辑本身有矛盾。典型触发场景:
- 基类函数没声明
virtual:void base_func()→ 派生类写void base_func() override报错 - 函数是静态的:
static void helper()→ 加override直接被拒 - 返回类型不协变:
Base*→ 派生类返回Derived*允许,但返回int就不行 - 基类该函数已被
final修饰:virtual void f() final→ 派生类再override就违法
和 virtual 一起用是否多余
不推荐写 virtual void f() override。虽然语法合法,但语义冗余:override 已隐含“这必然是虚函数”,再加 virtual 容易让人误以为它还能被进一步重写(其实不会,override 不影响虚性传递)。更清晰的做法是只写 void f() override。
真正容易被忽略的是:如果基类虚函数带 noexcept,派生类重写也必须带(否则不匹配),而这个约束不会自动继承,override 会把它揪出来——这点连很多老手都会漏。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











