函数的重载
在学习c++的过程中,除了函数重载,你即将还会遇到运算符重载,那么重载到底是什么意思呢?
所谓重载,就是”一物多用”。所谓函数重载,就是对一个函数名重新赋予它新的含义,使一个函数名可以多用;即用同一个函数名定义多个函数,这些函数的参数个数和参数类型不同。
例如,编写程序求三个数中的最大值(分别考虑整数、单精度数、长整形的情况)
int add(int left, int right)
{
return left + right;
}
float add(float left, float right)
{
return left + right;
}
long add(long left, long right)
{
return left + right;
}
int main()
{
int a = add(5, 2);
cout << "a= " << a << endl;
float b = add(5.1f, 2.0f);
cout << "b= " << b << endl;
long c = add(5L, 2L);
cout << "c= " << c << endl;
return 0;
}
运行情况如下:
我们可以看到,一个函数名分别定义了3个函数。那么在调用时怎样决定选择哪个函数呢?系统会根据调用函数是给出的信息去找与之匹配的函数。上面的main函数3次调用add函数,而每次实参的类型不同,系统会根据实参的类型找到与之匹配的函数(通过this指针),然后调用该函数。
这就是函数重载,但是上面3个add函数的函数体是相同的,其实重载函数并不要求函数体相同。重载函数除了允许参数类型不同外,还允许参数的个数不同。
举个例子:
编写程序,求出2个整数或3个整数中的最大值
int max(int a, int b, int c)
{
if (b > a)
a = b;
if (c > a)
a = c;
return a;
}
int max(int a, int b)
{
return a > b ? a : b;
}
int main()
{
int a = -1;
int b = 20;
int c = 94;
cout << "max(a,b)= " << max(a, b) << endl;
cout << "max(a,b,c)= " << max(a, b, c) << endl;
return 0;
}
运行结果如下:
两次调用max函数的参数个数不同,系统就会根据参数的个数找到与之匹配的函数并调用。
重点来了!!!
参数的个数和类型都可以不同,但是不能只用函数的类型不同而参数的个数和类型相同。
再举个例子吧、
int add(int,int)
{
}
float add(int,int)
{
}
int main()
{
int a = add(5, 2);
cout << "a= " << a << endl;
float b = add(5.1f, 2.0f);
cout << "b= " << b << endl;
}
我么来看一下运行结果:
通过上面这么多例子,可以很明确的看出:重载函数的参数个数、参数类型或参数顺序3者中必须至少有一种不同,函数的返回值类型可以相同也可以不同。
那么,做个总结吧
引用
c++最大的一个特点,就是对一个数据可以使用“引用”。
引用是一种新的变量类型,作用是为一个变量起一个别名。
引用的一般形式:类型& 引用变量名(对象名)=引用实体
例如:
int a = 10;
int& ra = a;
这两条语句声明了ra 是a的引用,即 ra 是 a 的引用。
注意:
1、 &是引用操作符,并不代表地址。
那么问题来了,如何区分是声明引用变量还是取地址的操作呢?
当&a 的前面有类型符时(如int &a),它必然是对引用的声明;如果前面无类型符(如 cout<<&a),则是取变量的地址。
2、声明变量 ra 为引用类型,并不需要另外开辟内存单元来存放 a 的值。
3、ra 和 a 占用内存中的同一个存储单元,他们具有相同的地址。
4、在声明变量 ra 是 a 的引用后,该引用类型变量 ra 始终与其代表的变量 a 相联系,不能再作为其他变量的引用。
5、 引用类型必须和引用实体类型一致。
6、声明一个引用变量时,必须同时使之初始化。
引用应用场景的
作为函数参数
到目前为止,我们学过的函数参数传递主要有两种方法:传值和传地址。
(一)传值:将变量名作为实参和形参,这时传给形参的是变量的值,传递是单向的。
举个例子:实现两个数的交换
通过代码执行结果可以看出,在执行函数期间形参的值发生改变,并不传回给实参。
那么,通过什么方法可以实现呢?我们想到了传递变量地址。
(二)传地址:即传递变量的指针;形参是指针变量,实参是一个变量的地址,调用函数时,形参指向实参变量单元。即代码可以改进为以下方式:
void swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}
int main()
{
int a = 10;
int b = 20;
swap(&a, &b);
printf("a=%d\n b=%d\n", a, b);
return 0;
}
运行结果为:
这种方法即为“值传递”方式,只是实参的值是变量的地址而已。通过形参指针变量访问主函数中的变量,并改变它们的值。
这种方法虽然可以实现,但在概念上却很难理解,不那么简洁,在c++中,把引用类型变量作为函数形参,就弥补了这个不足。
依然是先看代码:
void swap(int &ra, int &rb)
{
int tmp = ra;
ra = rb;
rb = tmp;
}
int main()
{
int a = 10;
int b = 20;
swap(a, b);
cout << a << " " << b << endl;
system("pause");
return 0;
}
运行结果如下:
在swap 函数的形参列表中声明 a 和 b 是整形变量的引用。当 main 函数调用 swap 函数时,由实参把变量名传给形参。a 的名字传给引用变量 ra,这样 ra 就是 a 的别名,同理, rb 是 b 的别名,它们都共用同一个地址空间,所以改变 ra 和 rb ,就是改变 a 和 b。
请思考:这种传递方式和使用指针变量作形参时有什么不同?