C++函数中的引用
2016-05-30 21:51
239 查看
第一篇博客,献给C++引用了
“&”在这里只是标示符,标示变量为引用类型,不是取地址运算!
“&”在这里只是标示符,标示变量为引用类型,不是取地址运算!!
“&”在这里只是标示符,标示变量为引用类型,不是取地址运算!!!
重要的事情说三遍~
原来在看其他人的代码的时候,经常有返回引用和引用传值的做法,当时并不明白这么做的原因,经过一番研究,算是有点儿小清楚了,写篇博客,希望各位同行前辈的给予指导,希望大家共同进步。
“&”感觉与“*”在很大程度上比较类似,但是“&”更加的安全。
个人认为主要原因下面这几个方面:
指针在初始化的时候可以为空,引用在初始化的时候不能初始化空;
指针可以根据代码需要修改指向的数据,但使用过程中不能修改指向的变量。
另外,引用变量的内存占用大小和指向的变量占用的内存大小一致,但指针为整数所占大小,在32位机内为4个字节。
本文标题为“C++函数中的引用”,所以重点讲一下引用吧,指针等有机会再写。
看了好多示例代码,暂时把引用在函数中的用法分为两类:引用传递和返回引用。
我们都知道,函数传参有三种方式:值传递、指针传递、引用传递,本文重点说明值传递与引用传递
值传递代码:
上面两个函数中,我们都知道swap1是不能达到交换两个变量的目的的,而swap2可以,因为swap2中采用的是引用传递。
值传递只是在函数传参时,将两个实参复制一份儿,分别复制给p和q,实际在函数体内操作的,并不是实参,而是形参,即p和q,一旦函数体结束,p和q所占的空间被释放,这个函数的操作也随之消失,产生不了任何效果。
但在swap2中,函数采用的是引用传递,可以理解为,p和q分别是对应实参的一个别名,对p和q 的操作,实际上就是对实参的操作,就算函数结束,p和q被释放,但是操作已经应用到了两个实参本身,这个函数也就起到了交换的作用。
以上就是值传递和引用传递的区别,那在很多场合,采用引用传递的原因也就显而易见了,
如果是值传递,在调用函数的位置,要先初始化两个变量,在把实参的值复制给形参,函数结束后,还要释放两个形参,由此完成了函数调用。
如果是引用传递,则在调用位置直接把两个实参传递给函数,函数结束后,不需要释放实参,就完成了函数调用,由此看来,通过引用传递,在系统复杂的情况下,可以有效的提高代码运行效率。
那么问题来了,有的时候并不想修改实参的值,比方说打印某个对象的一些属性,但是我们都知道,引用传递时,如果在函数体内不小心修改了实参的值,在函数结束调用后,其修改的结果依然有效,那如何在代码高效的情况下,保证数据的安全性呢?这个时候,就不得不提一个很神奇的关键字——const,通过const的修饰,就可以保证函数体内数据的安全,这也是为什么我们经常看到
const 和 ”&“经常一起出现的原因。函数声明示例如下:
第一行和第二行输出一致,同为变量 i 所处的地址,第三个地址输出是vr 的地址,与 i 的地址不同,第四个rr地址的输出,与 i 的地址相同,我们可以理解为rr为i的一个别名,不需要进行初始化,则优势同样很明显。
就目前来看,引用的使用可以大大提高代码的运行效率,但是对于引用的使用,尤其是返回引用的使用,还是有很多需要注意的地方,如果有兴趣,大家可以参考截图上方的地址,感觉写的挺全面的。
第二部分写的有点儿少,而且写的时候自己还是有点儿不太明白,总感觉大概意思是这样,就先这么写上吧,等以后慢慢的体会,再做修改,还希望各位同行前辈们多多指导哈!
“&”在这里只是标示符,标示变量为引用类型,不是取地址运算!
“&”在这里只是标示符,标示变量为引用类型,不是取地址运算!!
“&”在这里只是标示符,标示变量为引用类型,不是取地址运算!!!
重要的事情说三遍~
原来在看其他人的代码的时候,经常有返回引用和引用传值的做法,当时并不明白这么做的原因,经过一番研究,算是有点儿小清楚了,写篇博客,希望各位同行前辈的给予指导,希望大家共同进步。
“&”感觉与“*”在很大程度上比较类似,但是“&”更加的安全。
个人认为主要原因下面这几个方面:
指针在初始化的时候可以为空,引用在初始化的时候不能初始化空;
指针可以根据代码需要修改指向的数据,但使用过程中不能修改指向的变量。
另外,引用变量的内存占用大小和指向的变量占用的内存大小一致,但指针为整数所占大小,在32位机内为4个字节。
本文标题为“C++函数中的引用”,所以重点讲一下引用吧,指针等有机会再写。
看了好多示例代码,暂时把引用在函数中的用法分为两类:引用传递和返回引用。
1.引用传递
最初对引用传递的使用在处在通过一个函数修改多个变量的认知水平中,后来项目越做越多,代码看的也越来越多,才发现引用传递还可以这么用!我们都知道,函数传参有三种方式:值传递、指针传递、引用传递,本文重点说明值传递与引用传递
值传递代码:
void swap1(int p,int q) { int temp; temp=p; p=q; q=temp; }引用传递代码:
void swap2(int &p,int &q) { int temp; temp=p; p=q; q=temp; }
上面两个函数中,我们都知道swap1是不能达到交换两个变量的目的的,而swap2可以,因为swap2中采用的是引用传递。
值传递只是在函数传参时,将两个实参复制一份儿,分别复制给p和q,实际在函数体内操作的,并不是实参,而是形参,即p和q,一旦函数体结束,p和q所占的空间被释放,这个函数的操作也随之消失,产生不了任何效果。
但在swap2中,函数采用的是引用传递,可以理解为,p和q分别是对应实参的一个别名,对p和q 的操作,实际上就是对实参的操作,就算函数结束,p和q被释放,但是操作已经应用到了两个实参本身,这个函数也就起到了交换的作用。
以上就是值传递和引用传递的区别,那在很多场合,采用引用传递的原因也就显而易见了,
如果是值传递,在调用函数的位置,要先初始化两个变量,在把实参的值复制给形参,函数结束后,还要释放两个形参,由此完成了函数调用。
如果是引用传递,则在调用位置直接把两个实参传递给函数,函数结束后,不需要释放实参,就完成了函数调用,由此看来,通过引用传递,在系统复杂的情况下,可以有效的提高代码运行效率。
那么问题来了,有的时候并不想修改实参的值,比方说打印某个对象的一些属性,但是我们都知道,引用传递时,如果在函数体内不小心修改了实参的值,在函数结束调用后,其修改的结果依然有效,那如何在代码高效的情况下,保证数据的安全性呢?这个时候,就不得不提一个很神奇的关键字——const,通过const的修饰,就可以保证函数体内数据的安全,这也是为什么我们经常看到
const 和 ”&“经常一起出现的原因。函数声明示例如下:
void function(const Class& Var);<span style="white-space:pre"> //引用参数在函数内不可以改变
void function(const TYPE& Var);<span style="white-space:pre"> //引用参数在函数内为常量不可变以上就是在引用在函数传值上的应用。
2.返回引用
个人认为返回引用和引用传递的目的都是提高代码的运行效率,在第一部分说的太多了。不如代码来的实在,先上一段代码,大家感受下:#include <iostream> using namespace std; int j=3; //j是全局变量 int val() { int i = 1; return i; } int &ref() { // int j=3;j不能是局部变量! int &i = j; cout << "The address of i:" << &i << endl; return i; //不能返回局部对象的引用 } int main() { int vv = val(); int rv = val(); //int &rv = val()错误!val()返回的是一个int型的数,而给引用&rv 赋值的必须是一个同类型的变量。 int vr = ref(); int & rr = ref(); cout<<vv<<endl; cout<<rv<<endl; cout<<vr<<endl; cout << "The address of vr:" << &vr << endl; cout<<rr<<endl; cout << "The address of rr:" << &rr << endl; return 0; }事先声明,上面这段代码,并不是原创,原创地址为:http://www.cnblogs.com/fly1988happy/archive/2011/12/14/2286908.html,为了更好的理解返回引用,我在他的代码上加了一个地址输出,运行结果如下图:
第一行和第二行输出一致,同为变量 i 所处的地址,第三个地址输出是vr 的地址,与 i 的地址不同,第四个rr地址的输出,与 i 的地址相同,我们可以理解为rr为i的一个别名,不需要进行初始化,则优势同样很明显。
3.总结
就目前来看,引用的使用可以大大提高代码的运行效率,但是对于引用的使用,尤其是返回引用的使用,还是有很多需要注意的地方,如果有兴趣,大家可以参考截图上方的地址,感觉写的挺全面的。第二部分写的有点儿少,而且写的时候自己还是有点儿不太明白,总感觉大概意思是这样,就先这么写上吧,等以后慢慢的体会,再做修改,还希望各位同行前辈们多多指导哈!
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Python动态类型的学习---引用的理解
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- Shell脚本中引用、调用另一个脚本文件的2种方法
- vbs引用另一个vbs的代码
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法