override关键字用于显式声明重写虚函数,强制编译器检查签名一致性(含const、ref-qualifier、参数类型、返回类型协变等),不匹配则报错,提升编译期安全性。

override 关键字用来显式声明重写虚函数
它不是语法必需的,但能强制编译器检查:你写的函数是否真的在基类中存在对应的虚函数声明。如果签名不匹配(比如参数类型不同、const 修饰不一致、返回类型协变不满足),编译器会直接报错,而不是静默忽略或意外调用基类版本。
不加 override 可能导致重写失败却不报错
常见错误包括:
- 基类函数是
void func(int),子类写成void func(double)—— 这其实是重载,不是重写,override会让编译器立刻报错 - 基类函数是
virtual void func() const,子类漏写const—— 签名不一致,没override就悄无声息变成新函数 - 返回类型不满足协变规则(如基类返回
Base*,子类返回Derived*但没声明为指针/引用)——override触发检查
override 必须跟在函数声明末尾,且只用于成员函数
它不是修饰符,不能放在返回类型前,也不能用于非虚函数或静态函数。使用时要注意:
- 只能用于类定义内部的函数声明(.h 或类内定义),不能用于 .cpp 中的定义
- 必须和基类虚函数的 cv-qualifiers(
const/volatile)、ref-qualifiers(&/&&)完全一致 - 参数类型要逐个匹配,包括 typedef 展开后的实际类型(比如
size_t和unsigned long在某些平台不等价)
class Base {
public:
virtual void process() const = 0;
virtual std::string name() && = 0;
};
class Derived : public Base {
public:
void process() const override { / OK / } // ✅ 签名完全匹配
std::string name() && override { / OK / } // ✅
void process() override { / ❌ 缺 const,编译失败 / }
void process() const noexcept override { / ❌ 多了 noexcept,不匹配 / }
};
override 不影响运行时行为,只改变编译期检查强度
加上 override 不会生成额外代码,也不改变 vtable 布局或调用性能。它的价值纯粹在开发阶段防错:
立即学习“C++免费学习笔记(深入)”;
- 重构基类虚函数时,所有带
override的派生类函数会立即暴露不兼容问题 - 团队协作中避免因命名相似、参数微差导致的“以为重写了其实没重写”陷阱
- 现代 C++ 项目(C++11 起)应默认启用
-Woverloaded-virtual(Clang/GCC),再配合override形成双重保障
最容易被忽略的是 ref-qualifier 和异常规范(noexcept)的匹配——它们属于函数类型的一部分,但常被当成“可选修饰”,其实只要不一致,override 就会拒绝编译。










