C++:函数重载(你不知道的细节)
Posted 敲代码的Messi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++:函数重载(你不知道的细节)相关的知识,希望对你有一定的参考价值。
----------------------别让现实太饿,吃了梦想
前言
在不同的场景下,我们经常希望使用同一个函数名完成相同的任务,但是使用不同的参数列表。(例如:一个add函数完成两个int变量的相加,另一个add函数完成两个double变量的相加)
Ⅰ- 初识
我们通过一个实例来完成前言提到的例子:
int add(int a,int b){
return a+b;
}
double add(double a,double b){
return a+b;
}
int main(){
cout<<add(2,3)<<endl;
cout<<add(2.2,3.2)<<endl;
return 0;
}
这就是通过函数的重载完成一个简单的例子。
那这是对一个函数的重载吗?
两个函数的返回类型不同:
int add(int a,int b);
double add(int a,int b);
。
。
。
❌❌ 这不是函数重载
函数的重载关键我们在前言就提到过了----参数列表
Ⅱ- 函数特征标
函数的重载关键是 参数列表---- 函数特征标。
函数特征标不同的要求:
- 参数数目
- 参数类型
- 参数的排列顺序
C++允许定义名称相同的函数,但是前提需要是函数的特征标不同。
Ⅲ - 调用和原型匹配
函数调用时对多个定义的重载函数的选择----重载解析,是我们我们运用函数重载的难点。
1.强转
下面看一组测试:
声明:
void fun(int a); // #1
void fun(float a); // #2
void fun(char *s); // #3
调用:
fun(6.0); //to #2
fun(6); //to #1
fun("messi");//to #3
这似乎没什么问题,但是我们看这个调用:
long a=6;
fun(a);
它将与哪一个匹配? 它不与任何一个匹配! 因为 有两个函数都能接受以数字为实参。即使类型不匹配,但是有两种类型转换的反方式。 在这种情况下,C++会将其视为错误。
我们得到:函数重载中,在没有完全匹配的情况下,编译器只会接受有且只有一种可以强转的函数调用。
2.引用
声明:
void fun(int a); // #1
void fun(int &a); // #2
调用:
int a=6;
fun(a);
。
。
这也是错误的!
调用似乎和 #1是完全匹配的,但是对于编译器而言,这两个都匹配,在检查函数的特征标时,将类型引用和类型本身视为同一个特征标。
3.const
声明:
void fun(const int a);
void fun(int a);
调用:
int x=6;
fun(x);
.
.
.
两个函数声明都能接受调用,那会像引用一样报错吗?
不会报错!! 使用第二个原型。
对于const类型,编译器会根据实参是否为const来决定使用哪一个原型。
意思就是,编译器将== const== 和 非const 视为两个函数特征标。
Ⅲ - 名称修饰
在程序内部而言,如何跟踪多个名字相同的重载函数呢?意思就是 编译器是如何区分这些重载函数的?
C++编译器通过-----名称修饰 来完成。
比如说 :void fun(int a)
这种格式对于我们来言很适合,但是对于对于编译器来说并不友好,编译器会转换为自己的内部表示。
值得注意的是: 不同的编译器,对同一函数的名称修饰是不一样的。
这个可能会造成什么问题呢?
假设我们将自己的函数装入库中,到程序的链接阶段,链接器无法将一个编译器生成的函数调用和另一个编译器生成的函数定义匹配。
以上是关于C++:函数重载(你不知道的细节)的主要内容,如果未能解决你的问题,请参考以下文章