【笨木头C++】基与基础10:又是函数之引用
2015-12-29 18:38
411 查看
http://www.be
还记得之前说过,函数的参数用指针,可以避免拷贝产生额外的开销吗?
这次要来介绍一个类似的参数,那就是引用参数。
笨木头花心贡献,啥?花心?不呢,是用心~
转载请注明,原文地址:http://www.benmutou.com/archives/1928
文章来源:笨木头与游戏开发
引用可以理解为“别名”,粗俗地说,就是“外号”,代码中就是把yinyong这个变量作为num的外号。
以后yinyong就是num,num就是yinyong,给yinyong赋值,那么,num的值也会改变,因为它们是一样的。
这类似指针的*p。
从代码里就可以发现了,参数前面使用&符号,就是引用参数了,而参数的传递却不需要改变,我们不需要特意创建一个str的别名,然后再传递给函数。
直接把str传递进去就可以了。
这个时候,在version1函数里,可以改变str的值,因为这是引用,str就是s,s就是str,改变任何一个的值,另一个值也会被改变的。
那就是——不需要拷贝。
比如刚刚的代码,如果不使用引用的话,就要拷贝一次str的值,version1里的s就是拷贝的值。
使用引用之后,str就是s,s就是str,不存在拷贝的操作,可以节省内存和时间。
等等,这和指针怎么这么像?
是的,和指针很像,所以,什么时候用引用做参数,什么时候用指针做参数,也是很容易让人迷惑的。
这个迷惑的问题,等会再讨论。
这将会变得很复杂,复杂的同时又很强大。
比如:
因为字符串常量”nihao”默认是const char*类型,和函数指定的参数类型不一致,所以不能这么使用。
但是加上const就不一样了:
给引用参数加上const的好处就是:
1.如果实参的类型不正确,但是能够转换为正确的类型,那么,就会生成一个临时变量,这个临时变量就是转换后的正确类型。
2.如果实参的类型正确,但是,它不是左值,此时也会生成一个临时变量,作为参数使用。
第一条好处就是刚刚代码里的情况了,const char*是可以转换为string的,所以这次会自动生成一个string临时变量(值是”nihao”),s参数就是这个临时变量的别名。
第二条是什么意思呢?比如我们的函数是void version(int &num); 但调用的时候这么调用:version(888);
888类型是int,但明显不是左值,所以,这时也会生成一个int临时变量(值是888),num参数就是这个临时变量的别名。
为什么要这么麻烦的规则?
因为有时候不希望传递参数的时候要执行拷贝操作,所以要用引用参数。
但使用引用参数,就代表可以随意修改,并且会影响原来的值,这有时候不太安全。
所以就在引用参数前面加上const,这样,既不需要拷贝,也不能修改,两全其美。
而使用const后的两条规则,是为了可以更方便地使用函数,如果没有这样的规则,那么,很多时候都会报错。
比如使用version(888)会报错、使用version2(“nihao”)也报错,这会烦死人的。
大家记住引用的几个特点:
1.某个变量一旦作为另一个变量的引用(别名),就永远是那个变量的引用,不能换。这和指针不一样,指针变量随时可以指向其它的地址。
2.引用变量一定不会是空值的,比如int &yinyong = num; yinyong就是一个引用变量,它一定要初始化,不能这样:int &yinyong; 会报错的。所以引用变量一定不会是空值,这和指针变量不一样,指针变量是可以不初始化的(但这样很危险)。
3.在引用参数前面加上const,就拥有那两条规则,在很多时候会很方便。
于是,上面是引用的一些特点,当能够使用引用参数的时候,就使用引用参数,如果无法使用,或者使用起来很奇怪,那就选择使用指针参数。
这是基本的判断规则。
但,这么说肯定还是很模糊的,大家感兴趣的,可以百度一下“什么时候用引用参数,什么时候用指针参数?”,会找到很多讨论的话题。
都看一看,然后心中有个底,慢慢地就会清楚了。
继续,Fight…..(小若:所以说,为什么最后要用省略号,用感叹号不是比较有干劲么?)
nmutou.com/archives/1928【笨木头C++】
还记得之前说过,函数的参数用指针,可以避免拷贝产生额外的开销吗?
这次要来介绍一个类似的参数,那就是引用参数。
笨木头花心贡献,啥?花心?不呢,是用心~
转载请注明,原文地址:http://www.benmutou.com/archives/1928
文章来源:笨木头与游戏开发
1.什么是引用?
对于初学者来说,引用和取地址值操作可能会有点犯迷糊。int num = 10; int *p = # // 这是取地址操作 int &yinyong = num; // 这是引用
引用可以理解为“别名”,粗俗地说,就是“外号”,代码中就是把yinyong这个变量作为num的外号。
以后yinyong就是num,num就是yinyong,给yinyong赋值,那么,num的值也会改变,因为它们是一样的。
这类似指针的*p。
2.用引用作为函数参数
引用的主要用途是作为函数的参数,至于原因,晚点再说,先看看怎么用:// 函数定义 void version1(string &s) { } // 调用方式 string str = "hehe"; version1(str);
从代码里就可以发现了,参数前面使用&符号,就是引用参数了,而参数的传递却不需要改变,我们不需要特意创建一个str的别名,然后再传递给函数。
直接把str传递进去就可以了。
这个时候,在version1函数里,可以改变str的值,因为这是引用,str就是s,s就是str,改变任何一个的值,另一个值也会被改变的。
3.使用引用作为参数的好处?
为什么要用引用做参数?在参数前面加个&瞬间就变复杂了,不过,它还是有好处的。那就是——不需要拷贝。
比如刚刚的代码,如果不使用引用的话,就要拷贝一次str的值,version1里的s就是拷贝的值。
使用引用之后,str就是s,s就是str,不存在拷贝的操作,可以节省内存和时间。
等等,这和指针怎么这么像?
是的,和指针很像,所以,什么时候用引用做参数,什么时候用指针做参数,也是很容易让人迷惑的。
这个迷惑的问题,等会再讨论。
4.又是const
如果在引用参数前面加上const,又会是什么情况呢?这将会变得很复杂,复杂的同时又很强大。
比如:
// 这样一个函数 void version1(string &s) { } // 这样使用是允许的 string str = "nihao"; version1(str); // 这样使用是不允许的 version1("nihao");
因为字符串常量”nihao”默认是const char*类型,和函数指定的参数类型不一致,所以不能这么使用。
但是加上const就不一样了:
// 使用了const void version2(const string &s) { } // 这次可以这么使用了 version2("nihao");
给引用参数加上const的好处就是:
1.如果实参的类型不正确,但是能够转换为正确的类型,那么,就会生成一个临时变量,这个临时变量就是转换后的正确类型。
2.如果实参的类型正确,但是,它不是左值,此时也会生成一个临时变量,作为参数使用。
第一条好处就是刚刚代码里的情况了,const char*是可以转换为string的,所以这次会自动生成一个string临时变量(值是”nihao”),s参数就是这个临时变量的别名。
第二条是什么意思呢?比如我们的函数是void version(int &num); 但调用的时候这么调用:version(888);
888类型是int,但明显不是左值,所以,这时也会生成一个int临时变量(值是888),num参数就是这个临时变量的别名。
为什么要这么麻烦的规则?
因为有时候不希望传递参数的时候要执行拷贝操作,所以要用引用参数。
但使用引用参数,就代表可以随意修改,并且会影响原来的值,这有时候不太安全。
所以就在引用参数前面加上const,这样,既不需要拷贝,也不能修改,两全其美。
而使用const后的两条规则,是为了可以更方便地使用函数,如果没有这样的规则,那么,很多时候都会报错。
比如使用version(888)会报错、使用version2(“nihao”)也报错,这会烦死人的。
5.什么时候用引用参数,什么时候用指针参数?
这是一个不好回答的问题,一不小心可能就误导大家了。大家记住引用的几个特点:
1.某个变量一旦作为另一个变量的引用(别名),就永远是那个变量的引用,不能换。这和指针不一样,指针变量随时可以指向其它的地址。
2.引用变量一定不会是空值的,比如int &yinyong = num; yinyong就是一个引用变量,它一定要初始化,不能这样:int &yinyong; 会报错的。所以引用变量一定不会是空值,这和指针变量不一样,指针变量是可以不初始化的(但这样很危险)。
3.在引用参数前面加上const,就拥有那两条规则,在很多时候会很方便。
于是,上面是引用的一些特点,当能够使用引用参数的时候,就使用引用参数,如果无法使用,或者使用起来很奇怪,那就选择使用指针参数。
这是基本的判断规则。
但,这么说肯定还是很模糊的,大家感兴趣的,可以百度一下“什么时候用引用参数,什么时候用指针参数?”,会找到很多讨论的话题。
都看一看,然后心中有个底,慢慢地就会清楚了。
6.结束
看我发文章的速度越来越慢,就知道我快要坚持不住了。继续,Fight…..(小若:所以说,为什么最后要用省略号,用感叹号不是比较有干劲么?)
nmutou.com/archives/1928【笨木头C++】
相关文章推荐
- C++ Queues(队列)、Priority Queues(优先队列)
- C语言 字符串操作函数
- 我推荐的一些C\C++书籍
- Something about C
- c++ Const关键字
- __attribute__ ((__packed__)) 编译通不过
- C语言 基础之printf打印输出
- HDU5595:GTW likes math
- caffe源码c++学习笔记
- 格式化C语言命令indent
- Cannot load library: soinfo_link_image(linker.cpp:1635)
- VC++编写ActiveX控件
- QML中C++与ListModel交互摸索方案
- C++函数对象
- 二叉查找树(BST)的实现
- c++模板函数声明定义分离编译错误详解
- C语言判断一个数是否是回文数
- C++ string类中的字符串处理函数
- WindowsXP下 VC6.0 编译、安装Boost库
- C++实现遗传算法