C++函数重载和重写

目录 

函数重载

函数重写


函数重载

作用:函数名可以相同,提高复用性

函数重载条件:

1.同一个作用域下

2.函数名称相同

3.函数参数类型不同或者个数不同或者顺序不同

注意事项:

1.引用作为函数重载条件

#include<iostream>
using namespace std; 
void fun(int &a) {
    cout << "1" << endl;
}
void fun(const int &a) {
    cout << "2" << endl;
}
int main()
{
    fun(1);//调用const引用
    int a;
    fun(a);//调用非const引用
    return 0;
}

2.函数重载碰到默认函数

#include<iostream>
using namespace std; 
void fun(int a) {
    cout << "1" << endl;
}
void fun(int a,int b=10) {
    cout << "2" << endl;
}
int main()
{
    int a;
    //fun(a);//碰到默认参数有歧义需要避免
    return 0;
}

函数重载实现原理

C++利用命名倾轧(name mangling)技术,来改名函数名,区分参数不同的同名函数。命名倾轧是在编译阶段完成的。

#include<iostream> 
using namespace std; 
int func(int a,double b) 
{  
	return ((a)+(b)); 
} 
int func(double a,float b) 
{  
	return ((a)+(b)); 
} 
int func(float a,int b) 
{  
	return ((a)+(b)); 
} 
int main() 
{  
	return 0; 
}

d代表double,f代表float,i代表int,加上参数首字母以区分同名函数 

函数重写

函数重写是父类和子类的关系,是垂直关系

重载是同一个作用域下不同方法之间的关系,是水平关系

重写条件:

1.重写的函数和被重写的函数必须都为virtual函数,而且分别位于基类和派生类中

2.重写的函数和倍重写的函数,函数名和函数参数必须完全一致

3.重写的函数和被重写的函数,返回值相同,或者返回指针或引用,并且派生类虚函数返回的指针或引用的类型是基类中被替换的虚函数返回的指针或引用类型的类型

案例:

#include<iostream>
using namespace std;
class A {
public:
	virtual void fun() {
		cout << "A" << endl;
	}
};
class B :public A {
public:
	virtual void fun() {
		cout << "B" << endl;
	}
};
int main()
{
	A* p = new B();
	p->fun();
	return 0;
}

函数重写实现原理

存在虚函数的类中都有一个一维的虚函数表叫做虚表(vftable),类的对象有一个指向虚表开始的虚指针(vfpoint)。虚表是和类对应的,虚指针是和对象对应的。

当子类重写父类的虚函数的时候,会将从父类中继承来的虚表中父类原本的虚函数覆盖掉替换成子类的虚函数地址,从而实现多态

### C++函数重载重写的区别 #### 定义与基本概念 函数重载(Overload)指的是在同一作用域内定义多个具有相同名称但不同参数列表的函数。这种机制允许开发者通过不同的参数组合调用同一个函数名,从而提高代码的可读性灵活性[^3]。 而函数重写(Override),也称为覆盖,主要发生在继承关系中。当派生类提供了一个与其基类中虚函数签名完全一致的新实现时,则认为该函数重写了。这通常是用来支持动态绑定或多态行为的关键技术之一[^2]。 --- #### 主要区别对比表 | **特性** | **函数重载 (Overload)** | **函数重写 (Override)** | |---------------------|------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------| | **发生位置** | 同一作用域内 | 继承层次结构之间 | | **关键字需求** | 不需要特殊关键字 | 需要在基类中使用 `virtual` 关键字声明,并推荐在派生类中使用 `override` 显式标记 | | **参数列表要求** | 参数列表必须有所不同 | 参数列表必须严格匹配 | | **返回类型要求** | 返回类型可以不同 | 返回类型通常需保持一致,但在协变返回类型的条件下也可以有所变化 | | **目的** | 提供多种功能接口,使同一函数名适用于不同类型的数据 | 实现多态性,允许子类自定义父类的功能 | --- #### 示例代码展示 ##### 函数重载示例 以下是关于如何利用函数重载来适应不同输入的例子: ```cpp #include <iostream> using namespace std; class Example { public: void display(int value) { cout << "Integer Value: " << value << endl; } void display(double value) { cout << "Double Value: " << value << endl; } }; int main() { Example e; e.display(10); // 调用第一个版本 e.display(10.5); // 调用第二个版本 return 0; } ``` 上述例子展示了两个名为 `display` 的成员函数分别接受整型浮点型作为其唯一参数的情况[^3]。 --- ##### 函数重写示例 下面是一个典型的涉及虚拟函数以及重写的案例说明: ```cpp #include <iostream> using namespace std; // 基类 class Animal { public: virtual void sound() { cout << "Animal makes a sound" << endl; } // 声明为虚函数 }; // 派生类 Dog class Dog : public Animal { public: void sound() override { cout << "Dog barks" << endl; } // 使用 override 标记重写 }; // 派生类 Cat class Cat : public Animal { public: void sound() override { cout << "Cat meows" << endl; } // 使用 override 标记重写 }; int main() { Animal* myAnimal = new Dog(); myAnimal->sound(); // 输出 “Dog barks” delete myAnimal; myAnimal = new Cat(); myAnimal->sound(); // 输出 “Cat meows” delete myAnimal; return 0; } ``` 这里强调了只有当基类中的方法被指定成 `virtual` 类型之后,在衍生出来的类别里头对该方法所做的修改才会生效并体现出来[^2]。 --- ### 总结 综上所述,函数重载主要用于扩展单一命名下的操作多样性;而函数重写则是面向对象编程的核心部分——它实现了运行时期间的决策制定过程即所谓的“后期绑定”,进而达成真正的多态效果[^1]^。 --- 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值