1.为什么C++有函数重载但是C没有函数重载?
这涉及了C、C++的函数命名习惯,在C语言编译阶段,函数的命名不会受其参数列表的影响,即只要函数名相同编译出的函数名就相同。但在C++中,函数命名受影响,如下图所示,函数addss
在编译阶段的函数名是 ?addss@@YAHHH@Z,此处最后两个H可以相当于形参类型是int,正是因为函数名的不同,所以C++才能实现函数重载。同时这也说明了为什么返回类型不同不能视为函数重载的条件,因为你在调用函数的时候并没有说明你希望的函数返回类型,所以无法以返回类型作为判断你用的哪个函数的依据。另外,函数名称的作用是表示对应函数的第一条指令的地址,因此只有函数名不同,才能跳转到不同的函数。
2.引用
int main()
{
int b = 0;
int& a = b;
}
引用的一大显著特征就是类型名后面跟“&”,如上图a就是对b的引用。引用的作用类似与起了一个别的名称,这时候你调用别名和调用本名的作用是一致的( 如上图调用a和调用b效果相同),在分析一段代码的时候,可以直接将所有的引用用原本的引用对象替换即可,逻辑上不会有一点改变。
引用常用于函数,当引用做函数形参的时候,可以起到提高效率、做输出型参数的作用,注意引用可以做输出型参数的原因是引用的修改会影响到对于的实参。当引用做函数的返回值时,可以起到提高效率,修改返回对象的作用,但引用做函数的返回值有着一定的要求,如引用的对象在函数结束以后不能销毁,换言之引用的对象不能是函数中的临时变量,只能是如全局变量、静态变量、堆上开辟的等。
在上文中我提到过引用类似于起了一个别名,而现实中同一个事物可以有多个别名,因此同一个事物也可以有多个引用,如下图所示,a、c、d是对b的引用,所以他们的地址均是一样的,修改其中任意一个其余几个的内容均会改变。
引用本身存在一定限制,比如引用的必须是权限平移或者权限缩小,不能权限放大,此处的权限暂时可以粗略理解成变量本身的限制,比如const修饰的变量的权限最小,因此下图中的引用会报错,因为权限扩大了。(b是const修饰的,权限小于a,是权限扩大)。
那么下述代码为什么会报错呢,是因为类型不匹配吗?
答案是错误的,上述代码错误的原因是用double类型的b引用int类型的a,实际上引用的是一份临时变量,该临时变量类型是double,被a赋值,而该临时变量具有常量的特性,因此此处失败的原因还是权限扩大,那么该怎么修改才能对?在double前面加一个const,这样就是权限平移了。
像这种具有常量特性的临时变量,也包括函数返回一个临时变量,如下图的a被返回,ret引用的就是a的一份临时变量,同时,因为被引用了,所以这份临时变量的生存期也发生了改变,不会随着函数的结束而销毁。(此处切记不要与上述引用做函数返回类型搞混了,这里是引用了一个函数返返回值,函数返回的是int类型不是引用!)
另外还应当注意的一点是引用相当专一,当引用了一个对象以后就不能再引用别的对象,如下图
b是a的引用,就不能是c的引用了。
综上,本篇学习了函数重载的一些条件,初步认识了引用。