浅谈C++函数重载和引用

xiaoxiao2021-02-28  19

根据题目我们先来解释一下这两个名词到底是什么意思,避免初学者看到此博客一脸懵逼。

函数重载

函数重载:函数重载是函数的一种特殊情况,C++中允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(包括参数个数,参数类型和参数顺序)必须不同,常用来处理实现功能类似但数据类型不同的问题。简单理解就是“一物多用”。 说了这么多不如举个栗子可能会更加清晰, 例如: 我们要求出几种不同类型数据的和,以下给出代码

int ADD(int left, int right) { return left + right; } double ADD(double left, double right) { return left + right; } long ADD(long left, long right) { return left + right; } int main() { ADD(10,20); ADD(10.0,20.0); ADD(10L,20L); return 0; }

在代码主函数中可以看到,我们定义了三个函数名相同的函数,只有参数类型不同罢了,这时编译器并没有报错。这时,程序会根据实参不同的数据类型调用相对应的函数,这就是函数重载。至于为什么会调用相对应的的函数,后面我们在分析(this指针和_cedel调用约定) 从图片中我们可以得到一些结论: 在函数重载中,参数的类型和个数都可以不同,但不能只有函数的类型不同而参数的个数和类型相同。如果写成上述形式的话,编译器无法判别应该调用哪一个函数。因此,在函数重载中,我们应注意重载函数的参数类型,参数个数或参数顺序至少有一种不同,函数返回值类型可以相同也可以不相同。 这里给读者提供一个大牛对C++函数重载和各种调用约定的深入理解,有兴趣的人可以看看。 函数重载:http://www.cnblogs.com/skynet/archive/2010/09/05/1818636.html 调用约定:http://blog.csdn.net/lioncolumn/article/details/10376891

引用

引用:在这里它不是一个动词,它的作用是为一个变量起一个别名。既然是别名,那么就不需要给别名重新开辟一块内存空间,则以下例子中a和Ta共用同一块内存空间。

例如:

int a=10; //定义a是一个int类变量 int& Ta=a; //声明Ta是a的“引用”,变量Ta具有变量a的地址 //a=10 Ta=10

大家仔细观察会发现这里的引用在变量名前加了一个“&”,这里的“&”代表的不是地址,而是引用声明符。

char &Ta=a; //这里的&是引用声明符 char *p=&a; //这里的&是取地址符

那怎么来理解这句话呢?以上声明了Ta是a的引用,即Ta是a的别名,那我们就可以这样来表达这串代码的含义:通过Ta来引用a。

在引用变量时应注意以下几点: ⑴引用不是一种独立的数据类型,对引用只有声明么有定义。使用时必须先定义一个变量,在对这个变量进行引用(别名)。 ⑵声明一个引用时,必须同时使之初始化。当引用作为函数形参时不必再声明中初始化,他是在函数调用时自动实现的,即作为形参的引用是实参的别名。(下面我会提到在函数中引用作为形参) ⑶声明一个引用后就不能在作为另一个变量的声明。

⑷不能建立引用数组。 ⑸不能建立引用的引用,也没有引用的指针,例如:

⑹可以取引用的地址

int main() { int *p; int a=10; int &Ta=a; p=&Ta //把变量a的地址&a赋给指针P,即&Ta就是变量a的地址 }

⑺区别引用声明符和地址运算符

int main() { int a=10; int &Ta=a; //声明Ta是a的引用 cout<<&Ta<<endl; //打印a的地址,这里的&Ta不是引用

接下来我们讲一讲引用作为函数参数是怎么用的吧。 首先我们先回顾一下在C语言中交换两个数是怎么交换的吧。 交换两数的值有两种方法,一种是传值,一种是传址。

#include <iostream> using namespace std; //传值交换 void Swap1(int left, int right) { int temp = 0; temp = left; left = right; right = temp; } //传址交换 void Swap2(int* left, int* right) { int temp = 0; temp=*left; *left = *right; *right = temp; } int main() { int a = 10; int b = 20; Swap1(a, b); cout << a <<' '<< b << endl; Swap2(&a, &b); cout << a << ' ' << b << endl; return 0; }

从结果可以看来,传值并没有得到我们想要的结果,传址就可以,这是为什么呢? 这是因为在进行值传递时,传递是单向的,并且在调用函数时,系统为形参开辟一块临时空间,和实参并不在同一个存储单元,如果在执行函数期间形参发生变化,那么变化后的形参值并不会返回给实参。 优点:避免了函数调用的副作用 缺点:无法改变形参的值 而在进行传地址操作时,形参是指针变量,实参是一个变量的地址,调用函数时,指针变量得到实参的地址,此时,形参和实参都指向同一块地址空间,因此,在进行传址的情况下是能够交换两个数的。 指针虽然能够得到我们想要的结果但不是很形象友好,如果对指针不熟练那就可能造成意想不到的后果,那么,有没有一种既可以进行值传递,又能够达到址传递的效果呢? 聪明的科学家就想到了用引用来解决这个问题。

void Swap(int& left, int& right) //这里的&是引用声明符 { int temp = left; left = right; right = temp; } int main() { int a = 10,b = 20; int& Ta = a; int& Tb = b; Swap(Ta, Tb); cout << a << ' ' << b << endl; return 0;

这里怎么理解呢。首先,Ta 和 Tb 无疑是变量a和b的别名,在进行函数传参时,把实参 a 和 b 的地址传给了形参 left 和 right 。这样实参和形参得到的就是同一块地址空间,这样能够交换两个数也就是很容易理解了。

上面是引用的应用场景之一,引用还可以作为函数返回值

int& TestRefReturn(int& a) { a += 10; cout << a << endl; return a; } int main() { int a = 10; int& Ta = a; TestRefReturn(Ta); return 0; }

看到这里有人会问了,指针和引用到底有什么区别,结果都是能够交换两个数,你说引用可以避免指针的缺陷,到底是什么意思呢? 接下来我们就来讲一讲指针和引用的相同点和不同点:

相同点:从反汇编里面我们可以看出指针和引用在在底层里没有什么区别,都是按照指针的方式来实现的。 不同点: ①引用在定义时必须初始化,指针没有要求 ②一旦一个引用被初始化为指向一个对象,就不能再指向其他对象,而指针可以在任何时候指向任何一个同类型对象 ③没有NULL引用,但有NULL指针 ④在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址*空间所占字节个数 ⑤引用自加改变变量的内容,指针自加改变了指针指向 ⑥有多级指针,但是没有多级引用 ⑦指针需要手动寻址,引用通过编译器实现寻址 ⑧引用比指针使用起来相对更安全 好了 , 咱们C++中函数重载和引用就介绍到这里了,欢迎点评。 阿里嘎多!!!

转载请注明原文地址: https://www.6miu.com/read-2596178.html

最新回复(0)