目录
- 引用
- 引用概念
- 例子1
- 例子2
- 例子3
- 例子4
- 常引用
- 拓展
引用
引用概念
引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空
间,它和它引用的变量共用同一块内存空间。
比如:同学A有一个别名为张三,张三是同学A,张三和同学A指的都是同一个人,在C++中同学A可能是int类型,也可能是char类型,甚至可能是int*类型或int**类型…
因为引用的符号和去地址符号是相同的,就像之前的左移操作符和流插入一样,所以C++是可以同时支持取地址和引用的
例子1
#include<iostream>
using namespace std;
int main()
{int a = 0;int& b = a;cout << &b << endl;cout << b << endl;
}
这段代码中&b=a表示b是a的别名,打印的时候
cout<<&b<<endl表示打印a别名的地址
cout<<b<<endl则表示打印a的别名
注意:引用类型必须和引用实体是同种类型的
b既然是a的别名,b的地址也应该和a的地址一样(因为都表示的是同一个人)
那如果更改b的值,a的值是否又会更改呢?
显然是可以的,因为b就是a,只是换了个名字而已
例子2
别名是可以无限取的,就跟一个人的外号一样,不一定只有一个外号,同时也可以给一个人的外号取别名,比如同学B叫同学A为张三,同学C叫同学A为张四,有时同学C也爱叫张四为张五
int main(){int a = 0;int& b = a;int& c = b;int& d = a;cout << a << endl;cout << b << endl;cout << c << endl;cout << d << endl;return 0;}
例子3
对一个人取外号,这个人必须是存在的,所以引用在定义时必须初始化
如果我们写int &a=0,这样会被认为a是一个地址
例子4
一个变量可以有多个别名,而一个别名是不可以是多个变量的
int main(){int a = 0;int c = 1;int& b=a;int& b = c;return 0;}
再来看看下面这段代码
int main(){int a = 0;int& b = a;int c = 2;b = c;cout << b << endl;cout << a << endl;return 0;}
这里的b并不是c的别名,之前是 int& b = c,这里是b=c,只是将c对值赋值给b,但是b不是c的别名
常引用
常引用的出现是为了解决当引用作为参数传参时被修改的情况
void func(int& x)
{x++;
}
int main()
{int a = 0;int& b = a;b++;cout << a << endl;func(a);cout << a << endl;
}
这里的b作为a的别名,通过引用传参传进func函数中,func函数的x也是a的别名,所以x++,影响到了函数外的a
为了解决这种情况,可以用const去修饰
const修饰使参数的权限变小,让x不能被修改,但是可以给其他变量赋值
下面三张图也是因为const修饰引起的权限问题
coust修饰的int对象可以和其他coust修饰的int对象相加,因为权限都相同
所以可以得出结论,权限是不能放大的
比如下面的代码,我们对a进行const修饰,然后将a通过引用传参传给func函数中,最后会报错
void func( int& x)
{;
}
int main()
{const int a= 1;func(a);}
而当我们对func函数中的x用const修饰后就可以正常运行了,这是因为xa是被const修饰的,所以是不可以被更改的,而x作为a的别名理应也不可以被修改,但是x没有被const修饰,导致权限放大,所以才会报错
拓展
我们知道double类型传给int类型的时候会出现数据丢失,当我们用int类型的ri作为d的别名是会报错
但是当在int &ri前加const修饰后却可以正常运行
这里就需要知道类型转换的时候会产生临时变量,也就是说并不是d直接赋值给ri,而是通过d构造出一个int类型的临时变量
所以这里的ri是临时变量的别名,而我们知道临时变量是具有常性的,在没有const修饰的情况下是出现了权限放大,导致出错,而加上了const修饰后权限就相等了,所以没有报错
那为什么要产生临时变量呢?
int main()
{int i = 97;char ch = 'a';if (i == ch){cout << "i=ch" << endl;}}
当操作符两边的操作数类型不相等时会出现类型提升或者截断,像上边的const int&ri=d是将d整形的部分截断给临时变量,然后ri再去拷贝临时变量
而这里的char ch = 'a’是类型的提升,因为ch只占1个字节,而i是整形占4个字节,所以临时变量会占4个字节,将ch给临时变量,然后临时变量按类型提升的规则,最高位往上补0,最后ch的ASCLL码值和i相同,所以打印出i=ch