c++中的引用

一、概念

引用(类型& 变量),只是给一个已有的变量起了一个别名,在语法层次上讲,并不开辟新的空间


二、引用传参

下面用常见的Swap函数距离,下面的三个函数只有传参方式不同,分别是传值传参,传址传参和传引用传参


看一下结果,发现传值传参并不可以改变实参的值,而传址和传引用就可以成功交换x和y的值


不同 : 传址会为指针开辟新的空间,传引用只是取了一个别名,并没有开辟空间

相同 : 都可以在函数内部改变实参的值

可是如果在特定场景下,程序要求不改变实参的值,只是访问,那么用什么方法好呢?

其实如果要求不改变实参的值,很多人就想到那就用传值调用吧,但是如果你的变量不是一个单纯的int x,而是如下的一个结构体呢?

typedef struct Big
{
	int a[1000000];
	char b[1000000];
	//...很庞大的数据
}Big;

如果在这里选择传值调用,那么系统必须再开辟一个很庞大的结构体,很浪费系统时间空间资源

如果遇到了数据量很庞大,又不希望在函数内部改变实参的值得时候,我们可以选择用常引用传参


这样既节省了空间,又不担心数据在函数调用时改变

三、常引用


当你相对一个常数进行引用的时候,编译器会报错,那么怎样改正呢


其实把他改成常量引用就可以了,因为20自身应该属于一个 const int 类型的常量

在观察下面这种情况


当常量和别名类型不相同时,编译无法成功


代码改正为


四、引用做返回值

先看一个传值返回


和之前的例子一样,返回值的别名的权限不可放大,所以只要在把ret改为 const int型即可


下来再看一个传引用返回的例子


调试代码,我们发现一个很奇怪的现象


我们调用第二次Add函数的时候,并没有给ret赋值,但是ret的值却改变了


也就是说,ret 是 c的一个别名,如果我们在两次调用Add函数之间进行了其他的操作,那么 c 这块空间就可能是其他操作进行过程中形成栈桢,给这块空间赋予了一个随机值


传值和传引用返回的差别

    传值返回会形成一个中间的临时变量,而临时变量具有常性,需用const类型接收

    传引用返回,不会产生常量,他只是返回值那块空间的别名,但是,上例中的 c是Add函数的变量,他的生命周期只在Add函数的花括号里,一旦栈桢结束,空间就会被释放掉,这时候任意的函数都可以占用这块空间,所以 c 这块空间的值就是个不确定的值,而 ret 又是c的别名,所以 ret 也随时可能被修改,这并不是我们想要的结果,怎样才可以让 ret 的值不会改变?

    其实,如果 ret 所指代的空间( c )是一个在Add程序结束以后不会释放掉的空间,那么这块空间的就不能随意的被其他函数占用,也就是说,ret所指代的空间( c ),他的生命周期大于Add的生命周期就可以了

 总结: 尽量不要返回一个临时变量的引用

          如果出了作用于他还存在,就尽量使用引用(提高效率 :如果返回的是一个很大的空间,就不用再做一份临时拷贝)

          那么什么时候出了作用于他还存在呢?典型的就是 静态的,或者 全局的,或者是传参传进去的

五、汇编层看引用的特性


六、引用和指针的异同

1. 引用"从一而终",只能定义时初始化一次

指针变量的值可以改变

2. 引用必须初始化

指针可以不初始化

3.当使用sizeof时的意义不同

引用:sizeof是当前类型的字节大小

指针:sizeof是指针的字节大小

4. ++,--操作符意义不同

引用使用 ++,--操作符时加减的都是一个常量1

指针使用 ++,--操作符时加减的是指针所指类型字节的大小

5. 引用相对来说安全一些

指针可能会形成野指针,造成内存泄漏


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值