C++入门
1.函数重载
c++中支持在同一作用域调用同名函数,但是要求函数形参不同,可以是个数不同,类型不同。C语⾔是不⽀持同⼀作⽤域中出现同名函数的。
以上3种情况都可以,但下面有两种情况会报错
1.error C2556: “int fxx(void)”: 重载函数与“void fxx(void)”只是在返回类型上不同
因为调用时无法区分,所以返回类型不同无法作为重载条件。
void fxx()
{
}
int fxx()
{
}
2.error C2668: “fxxx”: 对重载函数的调用不明确
这两个函数虽然满足函数重载,但是因为缺省参数的存在导致调用时不知道调哪个函数
void fxxx()
{
}
void fxxx(int a = 10)
{
}
2.引用
2.1
引用是给已经存在的变量取一个别名,编译器并不会给它开辟一个新的空间,它与它引用的变量共用一个空间。比如你身份证上的名字与你的小名。
它的语法是 变量名& 引用别名 = 引用对象
C++中为了避免引⼊太多的运算符,会复⽤C语⾔的⼀些符号,⽐如前⾯的<<和>>,这⾥引⽤也和取地址使⽤了同⼀个符号&。
#include<iostream>
using namespace std;
int main()
{
int a = 3;
int& b = a;
int& c = a;
int& d = b;//相当于还是给a取别名
d++;
cout << a << endl;
cout << &a << endl;
cout << &b << endl;
cout << &c << endl;
cout << &d << endl;
}
可以看到a,b,c,d地址都一样
2.2引用的特性
• 引⽤在定义时必须初始化
• ⼀个变量可以有多个引⽤
• 引⽤⼀旦引⽤⼀个实体,再不能引⽤其他实体
#include<iostream>
using namespace std;
int main()
{
int a;
int& b = a;
//error C2530: “b”: 必须初始化引用
int c = 20;
b = c;//这里并不是让b引用c,只是赋值
cout << a << endl;
cout << &a << endl;
cout << &b << endl;
cout << &c << endl;
return 0;
}
可以看到a,b的地址是一样的
2.3引用的使用
• 引用的实践主要是引用传参,引用作返回值时减少拷贝传参,提高传参效率,改变引用对象同时改变被引用对象的值。
• 引⽤传参跟指针传参功能是类似的,引⽤传参相对更⽅便⼀些。
• 引⽤和指针在实践中相辅相成,功能有重叠性,但是各有特点,互相不可替代。
<1>先来看引用传参的作用
引用功能1.做函数形参,修改形参影响实参。
引用功能2.做函数形参,是直接引用实参。但值传递时函数会为形参开辟空间并将实参的值拷贝到这块新空间中。
#include<iostream>
using namespace std;
void swap(int& a, int& b)
{
int tmp = a;
a = b;
b = tmp;
}
int main()
{
int c = 1;
int d = 2;
cout << c << " " << d << endl;
swap(c, d);
cout << c << " " << d << endl;
return 0;
}
可以看到c,d的值互换了,但并没有传地址,因为改变引用值就是改变被引用值
<2>接下来看引用返回的作用
首先需要了解返回值的函数,返回值时都是创建一个临时变量再将要返回的值拷贝在临时变量中再返回,并且返回的临时变量是常量不可改变。
eg:
因为这里返回的临时变量是常量,所以要注意一个操作
这里不可以改变传回来的值
所以要想解决这个问题就要用到引用返回
在这里并没有创建临时变量,直接返回全局域的a的值
int& f(int& a)
{
return a;
}
int main()
{
int a= 1;
f(a) += 1;
cout << a;
}
可以看到成功改变了传回的值
所以引用做返回值的类型,可以修改返回对象,减少拷贝提升效率。
那么我们为啥不无脑使用引用做返回值,因为这样做会发生一些问题,让我们来看看
而且会发生以下情况
可以看到我只是调用了fxxx()函数,并没有赋值x,但x的值却从0变成了1000。
这里可以这么理解,我x是这块空间的别名,func()调用结束后销毁还给系统了,
但我留了一把钥匙可以访问这个房间,而func()结束后,如果没有再次调用新函数,那我之前住过的房间还是我上次住的原样,x=0,但后来调用了fxxx(),虽然名字不同但基本逻辑相同,又在上次相同的空间,相当于住进了我上次住进的房间,所以x的值会随之改变。
也就是“悬垂引用”。
所以如果要引用返回需保证你返回的值的生命周期足够长,返回后仍有效。