当C++使用引用传递参数时,应当注意的问题
如果实参与引用参数不匹配,C++将生成临时变量。如果引用参数是const,则编译器在下面两种情况下生成临时变量:
实参类型是正确的,但不是左值
实参类型不正确,但可以转换为正确的类型
左值参数是可被引用的数据对象,例如,变量、数组元素、结构成员、引用和被解除引用的指针都是左值,非左值包括字面常量和包含多项式的表达式。定义一个函数
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
Double refcube(const double& ra){ Returnra*ra*ra;}double side = 3.0;double* pd = &side;double& rd = side;long edge = 5L;double lens[4]={2.3,3.4,4.5,6.7};double c1 = refcube(side); // ra 是sidedouble c2 = refcube(lens[2]); // ra是lens[2]double c3 = refcube(rd); // ra 是 rddouble c4 = refcube(*pd); // ra 是*pddouble c5 = refcube(edge); // ra 是临时变量double c6 = refcube(7.0); // ra 是临时变量double c7 = refcube(side+10.0); // ra 是临时变量 |
参数side lens[2] rd 和*pd都是有名称的、double类型的数据对象,因此可以为其创建引用,而不需要临时变量。但是edge虽然是变量,类型却不正确,double引用不能指向long。另一方面,参数7.0和side+10.0的类型都正确,但没有名称,在这些情况下,编译器都将生成一个临时匿名变量,并让ra指向它。这些临时变量只在函数调用期间存在,伺候编译器便可以任意将其删除
那么为什么对于常量引用,这种行为是可行的,其他情况下却不行呢?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
Void swapr(int& a,int& b){ Inttemp; Temp=a; A= b; B= temp;} |
在早期的C++较宽松的规则下,执行下面的操作将发生什么?
Long a = 3,b = 5;
Swapr(a,b);
这里的类型不匹配,因此编译器将创建两个临时的int变量,将他们初始化为3和5,然后交换临时变量的内容,而a和b保持不变
简而言之,如果接受引用参数的函数的意图是修改作为参数传递的变量,则创建临时变量将阻止这种意图的实现,解决方法是,禁止创建临时变量,下载的C++标准正是正阳做的、
现在来看refcube()函数,该函数的目的只是使用传递的值,而不是修改他们,因此临时变量不会造成任何不利的影响。反而会使函数在可处理的参数种类方面更通用。因此,如果声明将引用指定为const,C++将在必要时生成临时变量、实际上,对于形参为const引用的C++函数,如果实参不匹配,则其行为类似于按值传递,为确保原始数据不被修改,将使用临时变量来存储值、
(PS:如果函数调用的参数不是左值或与相应的const引用参数的类型不匹配,则C++将创建类型正确的匿名变量,将函数调用的参数的值传递给该匿名变量,并让参数来引用该变量)
应尽可能使用const
使用cosnt可以避免无意总修改数据的编程错误
使用const使函数能够处理const和非const实参,否则将只能接受非const数据
使用const引用使函数能够正确生成并使用临时变量
以上这篇C++ const引用、临时变量 引用参数详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。
当C++使用引用传递参数时,应当注意的问题的更多相关文章
- 【Qt】信号和槽对值传递参数和引用传递参数的总结
在同一个线程中 当信号和槽都在同一个线程中时,值传递参数和引用传递参数有区别: 值传递会复制对象:(测试时,打印传递前后的地址不同) 引用传递不会复制对象:(测试时,打印传递前后的地址相同) 不在同一 ...
- C++入门经典-例5.20-右值引用传递参数
1:使用字面值(如1.3.15f.true),或者表达式等临时变量作为函数实参传递时,按左值引用传递参数会被编译器阻止.而进行值传递时,将产生一个和参数同等大小的副本.C++11提供了右值引用传递参数 ...
- ECMAScript中所有参数传递的都是值,不可能通过引用传递参数
今天在看JavaScript高级程序设计(第三版)时,看到了这个问题:ECMAScript中所有参数传递的都是值,不可能通过引用传递参数. 在我的印象中,其他语言比如Java,C++等,传递参数有两种 ...
- mvc中view与controll之间传递参数时,可以使用url进行传递
mvc中view与controller之间传递参数时,可以使用url进行传递,但是在url的地址中需要加上“id=123”这样的东西才行. 具体如代码: window.location.href = ...
- 测试当前C环境的栈帧增长方向以及传递参数时的压栈顺序
前文链接:上次由于一个很常见的printf-bug(下文有提及)引发了我对栈的思考,并写下了一点总结.这次就尝试对不同的C环境进行实践,检测其传递参数的一些性质. 这是今天写的检查C环境的一段程序.能 ...
- C#形参,实参,值传递参数,引用传递参数,输出参数,参数数组的学习
1)形参 形参顾名思义就是形式上的参数,不是实际的参数,它代替实际传入方法的值.在方法体代码中代表了值本身参与运算.形参定义于参数中,它不同于方法体内局部变量,因为是一个变量,在它的作用域内不允许存在 ...
- 分页技术框架(Pager-taglib)学习三(pager-taglib中传递参数时中文乱码问题)
一.问题描述 问题: 使用<pg:param name="key" />标签传递中文参数时,会有乱码. 原因: 因为它默认是用gb2312来对添加的参数进行编码,如果你 ...
- 解决JS在url中传递参数时参数包含中文乱码的问题
1.传参页面JavaScript代码: function go_mark(id,jobname,headimgurl,nickname){ window.location.href = "m ...
- HTTP通过Get请求传递参数时特殊字符被转码的处理方式
有些符号在URL中是不能直接传递的,如果要在URL中传递这些特殊符号,那么就要使用他们的编码了. 编码的格式为:%加字符的ASCII码,即一个百分号%,后面跟对应字符的ASCII(16进制)码值.例如 ...
随机推荐
- Git-------常用操作记录
说明: 一般情况下,git要将内容提交到本地仓库,都是先将内容提交到暂存区,然后再从暂存区提交到本地仓库. 常用命令(一个简单的示例操作): git init:会默认创建一个分支,命名为master ...
- Vue 实现 登陆后打开主页面(登陆组件 + 主页面组件)
本次演示,项目所需iview,router 首先 在 views 目录 新建 两个 组件 ( login.vue ,index.vue ) login.vue <template> < ...
- nginx 访问控制模块
截图,代码截屏均引用自慕课网nginx相关教学视频 基于用户的访问控制模块 http_access_module 基于用户登录信任的模块 http_access_module 参数示意:address ...
- Practical, Dynamic Visibility for Games(可实现动态显示技术)
Practical, Dynamic Visibility for Games(可实现动态显示技术) 原文地址 1引言 游戏场景越来越复杂,包含的内容越来越多,动态显示技术很需要. 本文介绍2种互补的 ...
- Canvas实用库Fabric.js使用手册
简介什么是Fabric.js? Fabric.js是一个可以简化Canvas程序编写的库. Fabric.js为Canvas提供所缺少的对象模型, svg parser, 交互和一整套其他不可或缺的工 ...
- Https Get Post
#region Http 访问 public string GetHttpUrl(string Url) { try { HttpWebRequest request = (HttpWebReques ...
- hdu 5821 Ball 思维题
Ball Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submis ...
- codeforces gym #101873B. Buildings(Polya定理)
参考博客: https://blog.csdn.net/liangzhaoyang1/article/details/72639208 题目链接: https://codeforces.com/gym ...
- Vue2实践computed监听Vuex中state对象中的对象属性时发生的一些有趣经历
今天想实现一个功能,在全局中随时改变用户的部分信息.这时候就想到了用Vuex状态控制器来存储用户信息,在页面中使用computed来监听用户这个对象.看似一个很简单的逻辑,就体现了我基本功的不扎实呀. ...
- vue——父组件向子组件传递数据
看例子: //注册一个全局组件,组件标签名为child Vue.component('child', { props: ['msg'], //接收父组件传递的数据 template: '<h3& ...