多态的实现基础是重写而非重载。重载是编译期静态绑定,根据参数类型在编译时确定调用函数;重写是运行时动态绑定,通过虚函数机制依据对象实际类型决定执行版本。

多态的实现基础不是重载,而是重写。重载不参与多态机制,它只是编译期根据参数自动选函数;重写才是运行时多态的核心——通过基类指针或引用调用虚函数时,实际执行哪个版本,由对象的真实类型决定。
重载(Overload):同一作用域内的“同名不同参”
发生在同一个类或全局作用域中,函数名相同但参数列表必须不同(类型、个数或顺序任一不同)。返回类型、访问修饰符、是否带 virtual 都不影响重载判定。编译器在编译阶段就完成匹配,属于静态绑定。
- 不能仅靠返回类型不同来构成重载,否则编译报错
- 常见于构造函数、工具函数(如 print(int) / print(string))
- 与继承无关,子类定义的重载函数不会影响父类调用逻辑
重写(Override):继承体系中的“同名同参同返回”
发生在派生类对基类虚函数的重新实现,要求函数名、参数列表、返回类型(或协变返回类型)完全一致,且基类函数必须声明为 virtual。重写支持运行时多态,是实现接口统一、行为差异化的核心手段。
- 子类方法的访问权限不能比父类更严格(如父类 public,子类不能 private)
- C++11 起推荐显式使用 override 关键字,帮助编译器检查签名一致性
- 若基类函数无 virtual,即使签名相同,也属于隐藏(Hide),而非重写
为什么重载不构成多态基础?
多态的本质是“同一接口,多种实现”,且实现选择延迟到运行时。重载函数在编译时已确定调用目标,调用哪一版取决于实参的静态类型,而非对象的实际类型。例如:Base* p = new Derived(); p->func(5); 若 func 是重载函数,调用的是 Base 类中匹配 int 参数的版本;只有 func 是虚函数并被重写,才会真正调用 Derived 中的实现。
一个典型对比场景
假设 Base 类有 virtual void draw(); 和 void show(int); 两个函数:
- Derived 类中实现 void draw() override; → 是重写,支持多态
- Derived 类中新增 void show(double); → 是重载,只在 Derived 对象直接调用时生效
- Derived 类中写 void show(int);(基类无 virtual)→ 是隐藏,不是重写,Base* 指针调用仍走 Base::show(int)

















