- 1、本文档共9页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
问题背景
#include?iostream??
???
using?namespace?std;??
???
vectorint?doubleValues?(const?vectorint?v)??
{??
????vectorint?new_values(?v.size()?);??
????for?(auto?itr?=?new_values.begin(),?end_itr?=?new_values.end();?itr?!=?end_itr;?++itr?)??
????{??
????????new_values.push_back(?2?*?*itr?);??
????}??
????return?new_values;??
}??
???
int?main()??
{??
????vectorint?v;??
????for?(?int?i?=?0;?i??100;?i++?)??
????{??
????????v.push_back(?i?);??
????}??
????v?=?doubleValues(?v?);??
}??
先来分析一下上述代码的运行过程。
vectorint?v;??
for?(?int?i?=?0;?i??100;?i++?)??
{??
????v.push_back(?i?);??
}??
以上5行语句在栈上新建了一个vector的实例,并在里面放了100个数。
v?=?doubleValues(?v?)??
这条语句调用函数doubleValues,函数的参数类型的const reference,常量引用,那么在实参形参结合的时候并不会将v复制一份,而是直接传递引用。所以在函数体内部使用的v就是刚才创建的那个vector的实例。
但是
vectorint?new_values(?v.size()?);??
这条语句新建了一个vector的实例new_values,并且复制了v的所有内容。但这是合理的,因为我们这是要将一个vector中所有的值翻倍,所以我们不应该改变原有的vector的内容。
v?=?doubleValues(?v?);??
函数执行完之后,new_values中放了翻倍之后的数值,作为函数的返回值返回。但是注意,这个时候doubleValue(v)的调用已经结束。开始执行 = 的语义。
赋值的过程实际上是将返回的vectorint复制一份放入新的内存空间,然后改变v的地址,让v指向这篇内存空间。总的来说,我们刚才新建的那个vector又被复制了一遍。
但我们其实希望v能直接得到函数中复制好的那个vector。在C++11之前,我们只能通过传递指针来实现这个目的。但是指针用多了非常不爽。我们希望有更简单的方法。这就是我们为什么要引入右值引用和转移构造函数的原因。
左值和右值
在说明左值的定义之前,我们可以先看几个左值的例子。
int?a;??
a?=?1;?//?here,?a?is?an?lvalue??
上述的a就是一个左值。
临时变量可以做左值。同样函数的返回值也可以做左值。
int?x;??
int?getRef?()???
{??
????????return?x;??
}??
???
getRef()?=?4;??
以上就是函数返回值做左值的例子。
其实左值就是指一个拥有地址的表达式。换句话说,左值指向的是一个稳定的内存空间(即可以是在堆上由用户管理的内存空间,也可以是在栈上,离开了一个block就被销毁的内存空间)。上面第二个例子,getRef返回的就是一个全局变量(建立在堆上),所以可以当做左值使用。
与此相反,右值指向的不是一个稳定的内存空间,而是一个临时的空间。比如说下面的例子:
int?x;??
int?getVal?()??
{??
????return?x;??
}??
getVal();??
这里getVal()得到的就是临时的一个值,没法对它进行赋值。下面的语句就是错的。
getVal()?=?1;//compilation?error??
所以右值只能够用来给其他的左值赋值。
右值引用
在C++11中,你可以使用const的左值引用来绑定一个右值,比如说:
const?int?val?=?getVal();//right??
int?val?=?getVal();//error??
因为左值引用并不是左值,并没有建立一片稳定的内存空间,所以如果不是const的话你就可以对它的内容进行修改,而右值又不能进行赋值,所以就会出错。因此只能用const的左值引用来绑定一个右值。
在C++11中,我们可以显示地使用“右值引用”来绑定一个右值,语法是。因为指定了是右值引用,所以无论是否const都是正确的。
const?string?na
您可能关注的文档
- 注会经济法科目考点解读第06节 公司法律制度06.pdf
- 常用命令及rpm3.ppt
- 硬件描述语言VHDL到Verilog翻译.pdf
- 第九节 贷款审批-授信额度的决定因素.pdf
- GE水煤浆气化装置在齐鲁长周期运行实践.pdf
- 配置IPV6方法.doc
- 奇怪吸引子及分形.pdf
- 紫外漫反射光谱和其在化学中的应用.pdf
- 基于自动发电响应分布式电源集群能量优化管理系统.pdf
- sqlserver测试题和答案.doc
- 2025年8月 在全市防汛工作视频会议上的讲话.docx
- 在2025年市委常委班子集中整治问题整改工作专题会议上的讲话+党课:以过硬作风护航高质量发展以实干担当书写新时代“赶考”答卷.pdf
- 国有企业2025年在“贯彻党中央决策部署和国企改革要求方面、全面从严治党责任落实方面、基层党组织建设方面、巡察整改长效机制建设四个方面”巡察整改专题民主生活会存在的原因分析.docx
- 2篇 2025年在四届区委第十三轮巡察动员部署会议上的讲话.pdf
- 在理论学习中心组巡视整改专题学习研讨会议上的讲话+在省委巡视反馈问题整改部署会上的讲话+工作领导小组会议上的讲话.pdf
- 2篇 2025年在四届区委第十三轮巡察动员部署会议上的讲话.docx
- 2025年国企理论学习中心组巡视巡察专题民主生活会会前学习研讨+(2025年四个方面)巡察整改专题民主生活会个人发言提纲.docx
- 局党组、宣传部、纪委监委关于2025年上半年意识形态工作总结及2025年下半年工作打算.pdf
- 4篇 2025年在学习贯彻《中华人民共和国监察法实施条例》研讨交流会上的发言.pdf
- 在市委理论学习中心组中央城市工作会议精神专题学习研讨会上的发言.+关于传达中央城市工作会议精神的讲话提纲.docx
文档评论(0)