c++ 重载 与重写

重写就是在派生类中重写基类的虚函数,重写的函数一定要有一致的参数表和返回值。

重载是指编写一个与已有函数同门但是参数列表不一样的函数,参数列表:参数个数,类型,顺序

重载:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数(至少对于编译器来说是这样的)。如,有两个同名函数:function func(p:integer):integer;和function func(p:string):integer;。那么编译器做过修饰后的函数名称可能是这样的:int_func、str_func.对于这两个函数的调用,在编译器间就已经确定了,是静态的。也就是说,它们的地址在编译期就绑定了(早绑定),因此,重载和多态无关!

重写:和多态真正相关。当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的(调用的子类的虚函数的地址无法给出)。因此,这样的函数地址是在运行期绑定的(晚绑定)。

### C++函数重载重写的区别和用法 #### 1. 定义概念 - **函数重载**是在同一个作用域中定义多个同名函数,但这些函数的参数列表必须同(参数类型、数量或顺序)。这种机制使得程序员可以在同一作用域下使用相同的函数名称来实现同的功能[^3]。 - **函数重写**是在派生类中重新定义基类中的虚函数的行为。它通常发生在继承关系中,目的是为了实现多态性,从而改变或扩展基类的功能[^1]。 --- #### 2. 参数返回类型的差异 - 对于**函数重载**而言,其核心在于参数的同。即使返回类型同,也能作为区分重载的标准。只有当参数的数量、类型或者顺序发生变化时,才能构成有效的重载[^3]。 - 在**函数重写**的情况下,子类中的函数签名必须严格匹配父类中的虚函数签名(除了 `co-variant` 返回类型的情况),即函数名、参数列表以及常量修饰符都需一致[^1]。 --- #### 3. 使用场景 - **函数重载**适用于需要提供多种调用方式的情形。例如,在设计一个计算面积的函数时,可以针对圆形、矩形等形状分别编写具有同参数的同名函数[^2]: ```cpp double area(double radius) { return 3.14 * radius * radius; } double area(double length, double width) { return length * width; } ``` - **函数重写**则主要用于支持动态绑定或多态性的场合。比如在一个图形绘制系统中,可以通过让各个具体形状类覆盖通用绘图接口的方法来实现特定行为[^1]: ```cpp class Shape { public: virtual void draw() = 0; // 纯虚函数 }; class Circle : public Shape { public: void draw() override { // 子类重写了draw方法 cout << "Drawing a circle." << endl; } }; ``` --- #### 4. 继承独立的关系 - **函数重载**并依赖于继承结构;它可以存在于单个类内部甚至全局命名空间之中[^3]。 - 反之,**函数重写**总是伴随着继承而存在——只有当某个类是从另一个类派生出来的时候才可能出现这种情况,并且被重写的通常是带有 `virtual` 关键字声明的成员函数。 --- #### 5. 多态的支持程度 - **函数重载**本身具备运行时期间决定实际执行哪个版本的能力,因此无法直接参基于对象实例的实际操作形式的选择过程。 - 相较之下,由于涉及到虚拟表(vtable)机制的应用,所以通过**函数重写**能够达成真正的运行期多态效果,这正是面向对象编程的一大特色所在。 --- ### 示例对比 以下是关于两者的一个简单例子: ```cpp #include <iostream> using namespace std; // 函数重载示例 void display(int value){ cout<<"Integer Value:"<<value<<endl; } void display(float value){ cout<<"Float Value:"<<value<<endl; } // 类层次结构下的函数重写示例 class Base{ public: virtual void show(){ cout<<"\nBase Class Function"<<endl; } }; class Derived: public Base{ public: void show(){ // Overriding base class function cout<<"\nDerived Class Function"<<endl; } }; int main(){ int i=10; float f=20.5f; // 调用重载函数 display(i); display(f); // 测试重写 Base* bptr=new Derived(); // Upcasting bptr->show(); // Calls overridden method delete bptr; return 0; } ``` 在这个程序里,我们既展示了如何利用同类型的数据去触发相应的显示处理逻辑(`display`),也演示了一个典型的继承体系当中基础类别向衍生实体变量所引发的具体表现形态切换现象(`bptr->show()`). ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值