C++中重写、重载与隐藏的区别及实例解析
C++面向对象编程中常涉及同名函数的处理逻辑,主要分为重写、重载与隐藏。重写基于继承与虚函数实现动态多态;重载发生在同一作用域内依赖参数列表差异;而隐藏则因作用域不同或函数签名不匹配导致基类成员被屏蔽。掌握这三者的区别对于编写正确的派生类至关重要。
重写(Override)
第1步:理解重写的定义与作用
重写特指在基类和派生类的继承关系中,派生类重新定义由基类声明为 virtual(虚函数)的成员函数。其目的是让派生类提供特定的实现,从而在运行时根据对象类型调用相应的函数(动态多态)。
#include <iostream>
using std::cout;
using std::endl;
class Base
{
public:
Base(){};
~Base(){};
virtual void fun() {cout << "Base class" << endl;}
};
class Derived : public Base
{
public:
Derived(){};
~Derived(){};
void fun() override {cout << "Derived class" << endl;};
};
int main()
{
Derived DerivedClass;
Base BaseClass;
DerivedClass.fun();
BaseClass.fun();
}
输出结果为:
Derived class
Base class
第2步:执行重写的关键条件
要实现合法的重写,必须满足以下严格条件:
- 基类函数必须包含
virtual关键字。 - 派生类函数需保证返回值类型、参数个数、参数类型与基类一致。
- 访问修饰符可以改变(例如基类为
private,派生类可重写为public)。 - 推荐使用
override标识符显式声明,以利用编译器检查是否符合重写规则。
第3步:掌握协变返回类型(Covariant Returns)
在常规情况下重写要求返回类型完全相同。但如果函数返回的是指向类的指针或引用,则允许派生类返回指向自身的指针或引用。这被称为协变返回类型。
适用场景与代码示例:
class Base
{
public:
Base(){};
~Base(){};
virtual Base* fun2() {return this;};
};
class Derived : public Base
{
public:
Derived(){};
~Derived(){};
Derived* fun2() override {return this;};
};
如上代码所示,基类 fun2 返回 Base*,派生类覆盖后返回 Derived*。这是编译器和运行环境明确支持的协变特性。
重载(Overload)
第1步:理解重载的定义与触发条件
重载是指在同一可访问区(通常是同一个类或全局作用域)内,声明多个同名但参数列表不同的函数。系统根据调用时传入的参数类型、个数和顺序来决定调用哪一个函数。注意:仅靠返回类型不同不能构成重载。
常见重载形式:
int test(); // 无参 int test(int a); // 一个整型参数 int test(int a, double b); // 两个参数,类型分别为 int 和 double int test(string s); // 一个字符串参数
第2步:重载的注意事项
- 核心依据是函数签名(参数表),与返回值无关。
- 必须位于同一作用域。
- 静态成员函数可以与非静态成员函数构成重载关系(前提是参数不同)。
- 运算符重载本质上也是重载的一种特殊应用。
隐藏(Hide/Shadowing)
第1步:理解隐藏的定义
隐藏发生在不同作用域之间。当派生类定义了与基类同名的函数时,无论是否有 virtual,也无论参数是否相同,只要名称一致,派生类的函数就会“隐藏”基类中同名的所有函数版本(包括带参数和不带参数的)。
第2步:识别隐藏的后果与排查
隐藏的触发非常直接:作用域不同 + 函数名相同。
- 编译器查找规则:名字查找优先于类型检查。这意味着如果在派生类中找到同名函数,编译器会停止在基类中查找其他同名函数,导致无法使用基类的重载版本。
- 对比重写:重写是一种特殊的、设计良好的隐藏,它维护了多态行为并更新了虚函数表;而普通的隐藏通常意味着基类功能不可见,往往需要通过
using Base::func;或限定名访问来调用。
总结
正确区分三者是C++进阶的基础:
1. 重写关注继承链上的多态替换,要求 virtual 和签名一致。
2. 重载关注同一范围内的函数变体,依赖参数列表。
3. 隐藏是因作用域隔离导致的基类符号不可见现象,需特别注意避免意外遮蔽。
以上就是C++中重写、重载与隐藏的详细内容,更多关于C++面向对象技术的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













