C++11:右值引用和左值引用

1.decltype

decltype可以推导出一个表达式的类型,可以用这个类型定义变量。

测试代码

template<class T1,class T2>
void test1(T1 &a,T2 & b)
{decltype(a* b) ret;cout << typeid(ret).name() << endl;
}

2.范围for 

void test2()
{string s("hello world");for (char a  :  s){cout << a <<" " ;}
}

可以将,s的内容放到a变量中,然后自动遍历迭代。

3.auto

auto可以自动推断出类型,主要是解决迭代器的名字太长的原因。

这是string迭代器的类型,而且string这个类型名字还是比较短的。

有了auto就可以这么写,是不是感觉很爽。

void test3()
{string  s;auto it = s.begin();cout << typeid(it).name() << endl;
}

auto还可以做函数的返回值

auto test4()
{string s("hello world");return s;
}

但是不建议这么使用,一但出现函数调用函数,想看这个函数的返回值都很费劲。

auto test5()
{return 0;
}auto test6()
{return test5();
}
auto test7()
{return test6();
}
auto test8()
{return test7();
}

如果我这样套起来,本来我想看看test8返回什么,这时候就得一直向上找,最后找到test5才知道test8返回的是一个int。

4.左值引用和右值引用

先说结论

C++11新加的右值引用有什么意义,之前只有左值引用,我们传参和函数返回值的时候,可以用引用减少拷贝,提高效率,但是函数引用做返回值的如果是一个临时的变量,返回的时候,该对象会被销毁,引用返回就没有用了,但是右值引用可以间接的解决这个问题,进而提高效率。

这个test返回的是一个custorm类,函数返回都会创建一个临时变量,返回这个临时的变量。

左值引用还是右值引用都是给变量起别名。

我们之前学习的引用,都是左值引用。

1.什么是左值

左值是一个具有长久生命周期,可以被赋值,可以被修改,取地址的表达式。

以下都是左值

int a = 0;
int *pa = &a;
int arr[10] = {0};

2.什么是右值

右值是一个将亡值,快要死了生命周期很短,不能被修改,不能被取地址,一般都是临时对象,表达式的结果,函数返回值,字面常量。

5; //5字面常量就是右值int x 0 ,y = 1;
x + y; //结果就是右值
fun1();//返回值是右值

3.右值引用的意义

对右值的引用,就是给右值取别名。

1.左值引用解决了,传参的时候拷贝的问题。

2.左值引用解决了,函数返回非局部对象拷贝的问题。

3.但是左值引用并不能解决,局部对象返回拷贝的问题,局部对象出了函数作用域销毁,右值引用就是解决局部对象返回拷贝的问题。

4.返回局部对象的成本

示例代码

#include<iostream>
#include<string>class custorm
{
public:custorm(){}custorm(const custorm& s){std::cout << "custorm(const custorm& s)" << std::endl;_number = s._number;_name = s._name;_adress = s._adress;}const custorm& operator=(custorm s){std::cout << "const custorm & operator=(custorm s)" << std::endl;std::swap(_number, s._number);std::swap(_name, s._name);std::swap(_adress, s._adress);return *this;}private:int _number = 0;std::string _name = std::string();std::string _adress = std::string();
};custorm transaction()
{custorm a;std::cout << "buy"<< std::endl;return a;
}int main()
{custorm ret;ret = transaction();return 0;
}

编译器不优化返回需要付出的成本

一次构造和一次拷贝构造。

但是别忘了,custorm对象里有两个string,每个string还需要一次构造,和一次拷贝构造。

编译器优化返回需要付出的成本

不错只需要一次构造,但是还不够。

5.右值引用如何解决局部对象返回拷贝的问题

我们通过将拷贝构造重载一个右值引用的版本,将函数的返回值强行识别为右值,这样经过编译器优化,直接会调用右值引用的版本拷贝构造,构造ret,因为是右值,是将亡值,所以我们可以肆无忌惮的转移其资源,我们可以直接讲将亡值的资源,转移给要构造的对象,把要构造对象的资源转移给将亡值,这样将亡值死后还会把没用的资源释放,直接榨干其最大的价值。

template<class T>void swap(T &t){_number = t._number;_name = t._name;_adress = t._adress;}custorm(custorm&& s){std::cout << "custorm(custorm&& s)" << std::endl;swap(s);}

直接转移资源,一次拷贝都没有,效率大大提高。

6.move

为什返回的时候会直接调用右值引用版本的拷贝构造呢?

因为ret返回的时候,被编译器自动使用move(),将ret变成右值,会调用更适合自己的构造函数。

返回一个对arg的右值引用,这个帮手函数强制移动值的语义,即使值是一个变量:直接使用返回值,会使arg被认为是一个右值。

7.右值引用右值,右值的属性变为左值

之前右值的定义,右值一般都是不可以修改的,但是我们在拷贝构造的时候,却肆无忌惮的,转移资源,这就是因为右值引用右值,右值的属性变为左值,不然我们也不可能转移资源。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/6444.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

上位机图像处理和嵌入式模块部署(树莓派4b部署java环境)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 通常我们都会认为java是部署在pc服务器上面的&#xff0c;或者是用java开发android应用程序。其实不然&#xff0c;java也可以部署在嵌入式开发板子…

前端工程化03-贝壳找房项目案例JavaScript常用的js库

4、项目实战&#xff08;贝壳找房&#xff09; 这个项目包含&#xff0c;基本的ajax请求调用,内容的渲染&#xff0c;防抖节流的基本使用&#xff0c;ajax请求工具类的封装 4.1、项目的接口文档 下述接口文档&#xff1a; 简述内容baseURL&#xff1a;http://123.207.32.32…

ESP32 烧录固件

第一步&#xff1a;下载固件 git clone --recursive https://github.com/espressif/esp-at.git 第二步&#xff1a;执行编译 在该目录执行 python build.py install 如图&#xff1a; 第三步&#xff1a;选择芯片 输入2 第四步&#xff1a;选择固件 输入1 第五步&#…

error LNK2001: 无法解析的外部符号 “__declspec(dllimport) public: __cdecl ......

运行程序时&#xff0c;报如上图所示错误&#xff0c;其中一条是&#xff1a; ReflectionProbe.obj : error LNK2001: 无法解析的外部符号 "__declspec(dllimport) public: __cdecl osg::Object::Object(bool)" (__imp_??0ObjectosgQEAA_NZ) 报这个错误一般是因为…

银行ETL-监管报送

1104报表 1104报表主要包括&#xff1a;资产负债&#xff0c;表外业务、流动性风险、贷款质量、投向行业和地区、重点客户等。 1104报表分类 普通报表、机构特色类报表。 反洗钱 大额交易、可疑交易。标签分类&#xff1a;疑似犯罪、疑似毒品、疑似传销。 反洗钱—接口报…

揭秘Fabric交易流程:一文带你深入了解

随着区块链技术的日益普及&#xff0c;Hyperledger Fabric作为一种联盟链解决方案&#xff0c;受到了广泛关注。那么&#xff0c;Fabric的交易流程究竟是怎样的呢&#xff1f;本文将为您一一揭晓。 1. Fabric交易的参与方 客户端&#xff1a;交易流程的发起方&#xff0c;发起…

Windows 容器镜像踩坑记录

为什么研究windows容器&#xff1f;emm&#xff0c;公司需要&#xff0c;不想多说。 dotnet后端 问题描述&#xff1a; 基于mcr.microsoft.com/dotnet/aspnet:6.0镜像撰写dockerfile编译.net core后端项目后运行容器出现类库不存在问题&#xff1a; 程序中使用了fastreport&a…

数据库(MySQL)—— DQL语句(基本查询和条件查询)

数据库&#xff08;MySQL&#xff09;—— DQL语句&#xff08;基本查询和条件查询&#xff09; 什么是DQL语句基本查询查询多个字段字段设置别名去除重复记录 条件查询语法条件 我们今天进入MySQL的DQL语句的学习&#xff1a; 什么是DQL语句 MySQL中的DQL&#xff08;Data Q…

【论文】关于网页上能打开的文章下载PDF“显示无效或损坏的 PDF 文件”的解决办法

1. 遇到的问题 今天我在 dl.acm.org/doi 下载论文时发现下载后的pdf打开出现“显示无效或损坏的 PDF 文件” 可是在原网址是可以打开并显示的 2. 解决方案 这里我用到了和之前【论文】去除PDF论文行号的完美解决方案 的相似的解决办法 就是下载的时候不直接下载&#xf…

【前端项目——分页器】手写分页器实现(JS / React)

组件介绍 用了两种方式实现&#xff0c;注释详细~ 可能代码写的不够简洁&#xff0c;见谅&#x1f641; 1. 包含内容显示的分页器 网上看了很多实现&#xff0c;很多只有分页器部分&#xff0c;没和内容显示联动。 因此我增加了模拟content的显示&#xff0c;这里模拟了32条数…

环形链表面试题详解

A. 环形链表1 给你一个链表的头节点 head &#xff0c;判断链表中是否有环. 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置…

【数据结构】第四讲:双向链表

目录 一、链表的分类 二、双向链表的结构及实现 1.带头双向链表的结构 2.创建节点 3.初始化 4.尾插 5.打印 6.头插 7.尾删 8.头删 9.在pos位置之后插入数据 10.删除pos节点 11.查找 12.销毁 个人主页&#xff1a;深情秋刀鱼-CSDN博客 数据结构专栏&#xff1a;数…

虚拟化技术 安装并配置ESXi服务器系统

安装并配置ESXi服务器系统 一、实验目的与要求 1.掌握创建VMware ESXi虚拟机 2.掌握安装VMware ESXi系统 3.掌握配置VMware ESXi系统的管理IP 4.掌握开启VMware ESXi的shell和ssh功能的方法 二、实验内容 1.安装VMware workstation 15或更高版本 2.创建VMware ESXi虚拟…

专业渗透测试 Phpsploit-Framework(PSF)框架软件小白入门教程(三)

本系列课程&#xff0c;将重点讲解Phpsploit-Framework框架软件的基础使用&#xff01; 本文章仅提供学习&#xff0c;切勿将其用于不法手段&#xff01; 继续接上一篇文章内容&#xff0c;讲述如何进行Phpsploit-Framework软件的基础使用和二次开发。 当我们点击 submit 提…

基于t972 Android9 AP6256,如何在设置中添加5G热点选项,并使其正常打开

通过设置的的WiFi热点选项可以知道关键词“2.4GHz”&#xff0c;因此可以其全局搜索&#xff0c;在packages\apps\Settings\res\values\strings.xml文件下找到如下图所示&#xff0c; 从上面注释可以知道&#xff0c;选项按键选择2.4GHz触发的按键关键词是“wifi_ap_choose_2G…

✔ ★Java项目——设计一个消息队列(五)【虚拟主机设计】

虚拟主机设计 创建 VirtualHost实现构造⽅法和 getter创建交换机删除交换机创建队列删除队列创建绑定删除绑定发布消息 ★路由规则1) 实现 route ⽅法2) 实现 checkRoutingKeyValid3) 实现 checkBindingKeyValid4) 实现 routeTopic5) 匹配规则测试⽤例6) 测试 Router 订阅消息1…

分布式websocket IM即时通讯聊天开源项目如何启动

前言 自己之前分享了分布式websocket的视频有同学去fork项目了&#xff0c;自己启动一下更方便理解项目嘛。然后把项目启动需要的东西全部梳理出来。支持群聊单聊,表情包以及发送图片。 支持消息可靠&#xff0c;消息防重&#xff0c;消息有序。同时基础架构有分布式权限&…

深入教程:在STM32上实现能源管理系统

引言 能源管理系统&#xff08;EMS&#xff09;在提高能源效率、减少能源消耗和支持可持续发展方面起着关键作用。本教程将介绍如何在STM32微控制器上开发一个能源管理系统&#xff0c;这种系统能够监控和控制能源使用&#xff0c;适用于家庭自动化、工业控制系统以及任何需要…

jQuery Moblie 笔记14 开发跨平台移动设备网页

相关内容&#xff1a;jQuery Moblie基础、操作、移动设备仿真器、jQuery Moblie网页实例、jQuery Moblie的UI组件、…… jQuery推出了一套新的函数库jQuery Mobile&#xff0c;目的是希望能够统一当前移动设备的用户界面(UI)。 移动设备开发应用程序目前大致分为两种&#xff…

MLP手写数字识别(3)-使用tf.data.Dataset模块制作模型输入(tensorflow)

1、tensorflow版本查看 import tensorflow as tfprint(Tensorflow Version:{}.format(tf.__version__)) print(tf.config.list_physical_devices())2、MNIST数据集下载与预处理 (train_images,train_labels),(test_images,test_labels) tf.keras.datasets.mnist.load_data()…