C++中的左值,右值和移动语义详解

左值,右值与移动语义

  • 左值表示了一个占据内存中某个可识别位置的对象。右值是无法寻址的临时对象或表达式的值。左值可以隐式地转换为右值,而右值不可。右值可以显式地赋值给左值。
  • 赋值运算符、取地址符、内置解引用运算符、下标运算符、内置类型和迭代器的递增递减运算符,都需要左值。
  • 右值引用与移动语义是C++11中引入的两个重要概念,它们旨在提高代码的性能,尤其是在涉及到资源管理和对象转移的场景中。

右值引用:

右值引用是对临时对象(即右值)的引用,它允许开发者安全地获取临时对象的资源。右值引用使用两个&&符号表示,例如int&&。它与左值引用(使用单个&符号,例如int&)不同,左值引用只能绑定到持久性对象上。右值引用使得编译器能够区分哪些对象是临时的,从而可以安全地转移其资源。

移动语义:

移动语义允许对象的资源(如动态分配的内存)被转移而非复制。这通常通过实现移动构造函数和移动赋值运算符来实现。当一个对象被移动时,它的资源被转移到新对象中,原对象则处于一个有效但不确定的状态,通常被设置为一个不再持有资源的状态。这意味着移动操作通常比复制操作更快,因为它避免了不必要的资源复制。以下例子来自于:

#include <iostream>
#include <utility>  // for std::swapusing std::cout;class Intvec
{
public:explicit Intvec(size_t num = 0): m_size(num), m_data(new int[m_size]){log("constructor");}~Intvec(){log("destructor");delete[] m_data;}Intvec(const Intvec& other): m_size(other.m_size), m_data(new int[m_size]){log("copy constructor");for (size_t i = 0; i < m_size; ++i)m_data[i] = other.m_data[i];}Intvec(Intvec&& other): m_size(0), m_data(nullptr){log("move constructor");// swap the members of this class with the members of otherstd::swap(m_size, other.m_size);std::swap(m_data, other.m_data);}Intvec& operator=(const Intvec& other){log("copy assignment operator");Intvec tmp(other);std::swap(m_size, tmp.m_size);std::swap(m_data, tmp.m_data);return *this;}Intvec& operator=(Intvec&& other){log("move assignment operator");std::swap(m_size, other.m_size);std::swap(m_data, other.m_data);return *this;}private:void log(const char* msg){cout << "[" << this << "] " << msg << "\n";}size_t m_size;int* m_data;
};int main(){Intvec v1(20);Intvec v2;cout << "assigning lvalue...\n";v2 = v1;cout << "ended assigning lvalue...\n";cout << "assigning rvalue...\n";v2 = Intvec(33);cout << "ended assigning rvalue...\n";return 0;
}

运行结果:

[0x61ff00] constructor
[0x61fef8] constructor
assigning lvalue...
[0x61fef8] copy assignment operator
[0x61fec8] copy constructor
[0x61fec8] destructor
ended assigning lvalue...
assigning rvalue...
[0x61ff08] constructor
[0x61fef8] move assignment operator
[0x61ff08] destructor
ended assigning rvalue...
[0x61fef8] destructor
[0x61ff00] destructor

在main函数中,首先创建了一个Intvec对象v1,然后创建了另一个空的Intvec对象v2。接下来,执行了两次赋值操作:

  1. v2 = v1;:这是一个左值赋值,因为v1是一个左值。因此,调用了拷贝赋值运算符,创建了v1的一个副本给v2。
  2. v2 = Intvec(33);是一个右值赋值,因为Intvec(33)是一个临时对象,即一个右值。如果实现了移动赋值运算符,编译器会选择这个运算符来进行赋值,从而转移临时对象的资源给v2。如果没有实现移动赋值运算符,编译器会回退到使用拷贝赋值运算符,且v2
    =Intvec(33);的运行结果如下:
assigning rvalue...
[0x61ff08] constructor
[0x61fef8] copy assignment operator
[0x61fec8] copy constructor
[0x61fec8] destructor
[0x61ff08] destructor
ended assigning rvalue...

在第二次赋值操作中,如果实现了移动赋值运算符,临时对象的资源会被转移给v2,这通常比拷贝快得多,因为它避免了资源的复制。如果没有实现移动赋值运算符,则会调用拷贝赋值运算符,进行资源的复制。

同时可见,当同时存在拷贝赋值运算符(operator=)和移动赋值运算符(operator=)时,C++编译器会根据赋值操作的右侧操作数(即要赋值的对象)是左值还是右值来自动选择合适的赋值运算符。

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

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

相关文章

跨域怎么解决

跨域解决主要有以下⼏种&#xff1a; JSONP CORS Nginx代理 document.domain window.name postMessageiframe 1.JSONP 我们知道写 HTML 代码的时候&#xff0c;加⼊图⽚链接就不会有获取不到图⽚的问题。这是因为图 ⽚资源并没有进⾏ ajax 请求&#xff0c;⽽且 script…

Superset二次开发之环境部署(Windows版)

本地环境版本介绍: 编号 名称 版本 1supersetv3.0.0rc32Pythonv3.10.123Nodev16.20.24npmv8.19.45Anacondav3 1.下载源码 #下载源码 git clone https://github.com/apache/superset.git ##速度慢可替换为 https://gitclone.com/github.com/apache/superset.git #进入项目目录…

前端性能优化四十七:工程目录设计范式种类

1. 模块化: ①. 将一个复杂应用根据预设规范封装为多个块并组合起来:a. 对内实现数据私有化b. 对外暴露接口、其它模块通信②. 在前端工程化具体体现:a. 在文件层面上对代码与资源实现拆分与组装b. 将一个大文件拆分为互相依赖的小文件,再统一拼装与加载1. 工程目录设计范式种…

搜维尔科技:Geomagic Phantom Premium 1.5六自由度力反馈设备开箱测试!

搜维尔科技&#xff1a;Geomagic Phantom Premium 1.5六自由度力反馈设备开箱测试&#xff01; Geomagic Phantom系列产品中首屈一指的力反馈产品Phantom Premium 六自由度力反馈设备&#xff08;原Sensable&#xff09;能够提供高度精确的3D对象操作&#xff0c;使用户能够探索…

在Go中解析HTTP请求中的表单数据

想象一下&#xff0c;你收到了一封神秘的信件&#xff0c;信上写着&#xff1a;“在HTTP请求的表单数据中&#xff0c;隐藏着一座宝藏&#xff0c;等待勇敢的冒险者前来寻找。” 你知道&#xff0c;这封信正是冲着你来的&#xff01;今天&#xff0c;我们将使用Go语言作为我们的…

VMware17Pro虚拟机安装Linux CentOS 7.9(龙蜥)教程(超详细)

目录 1. 前言2. 下载所需文件3. 安装VMware3.1 安装3.2 启动并查看版本信息3.3 虚拟机默认位置配置 4. 安装Linux4.1 新建虚拟机4.2 安装操作系统4.2.1 选择 ISO 映像文件4.2.2 开启虚拟机4.2.3 选择语言4.2.4 软件选择4.2.5 禁用KDUMP4.2.6 安装位置配置4.2.7 网络和主机名配置…

GBASE南大通用数据库分享访问多个数据库的 SQL 语句

您可跨数据库和跨数据库服务器实例运行下列 SQL 语句&#xff1a; • CREATE DATABASE • CREATE SYNONYM • CREATE VIEW • DATABASE • DELETE • DROP DATABASE • EXECUTE FUNCTION • EXECUTE PROCEDURE • INFO • INSERT • LOAD • LOCK TABLE • MERGE • SE…

web自动化测试的智能革命:AI如何推动软件质量保证的未来

首先这个标题不是我取的&#xff0c;是我喂了关键字让AI给取的&#xff0c;果然非常的标题党&#xff0c;让人印象深刻&#xff0c;另外题图也是AI自动生成的。 先简单回顾一下web自动化测试的一些发展阶段 QTP时代 很多年前QTP横空出世的时候&#xff0c;没有人会怀疑这种工…

java判断时间是否为节假日(或指定的日期),是的话返回true,否返回false

这个方法属实有点老套&#xff0c;先定义set&#xff0c;需要手动输入要判断的时间才行。 这个代码&#xff0c;就是输入一个日期&#xff0c;来判断这个日期是否为你指定的日期。如果是的话&#xff0c;返回true&#xff0c;否的话返回false。 代码&#xff1a; package Lx…

软考高级考完了,怎么评职称?

每年考试结束后&#xff0c;总有朋友问我&#xff0c;考完后怎么才能评上职称呢&#xff1f;获得证书就意味着获得了职称吗&#xff1f;让我们一起来看看具体情况吧&#xff01; 01\职称获取途径 获得职称可以通过认定、评审、国家统一考试(以考代评)、职业资格对应等多种方式…

轻松设置CentOS IP地址的最终指南:详细的分步说明

轻松设置CentOS IP地址的最终指南 一、引言二、准备工作三、手动设置IP地址四、自动分配IP地址(DHCP)五、使用网络管理工具设置IP地址5.1、使用nmtui工具进行图形化设置5.2、使用nmcli命令行工具进行设置 六、常见问题和解决方案七、总结 一、引言 CentOS操作系统是一种基于Li…

【华为OD机试真题2023CD卷 JAVAJS】电脑病毒感染

华为OD2023(C&D卷)机试题库全覆盖,刷题指南点这里 电脑病毒感染 知识点广搜 题目描述: 一个局域网内有很多台电脑,分别标注为0 - N-1的数字。相连接的电脑距离不一样,所以感染时间不一样,感染时间用t表示。 其中网络内一个电脑被病毒感染,其感染网络内所有的电脑需…

mysql怎么只允许指定IP访问

要查看MySQL数据库中连接成功的历史IP地址&#xff0c;你可以查询MySQL的日志文件或使用以下SQL查询来获取相关信息&#xff1a; 查看MySQL的日志文件&#xff1a; 打开MySQL配置文件&#xff0c;找到log-bin参数。该参数用于启用二进制日志&#xff08;Binary Logging&#x…

LLM(八)| Gemini语言能力深度观察

论文地址&#xff1a;https://simg.baai.ac.cn/paperfile/fc2138ce-cadb-4a36-b9f7-c4000dea3369.pdf 谷歌最近发布的Gemini系列模型是第一个在各种任务与OpenAI GPT系列相媲美的模型。在本文中&#xff0c;作者对Gemini的语言能力做了深入的探索&#xff0c;做出了两方面的贡献…

服务案例|CIS数据库故障问题

一、告警通知 12月20日凌晨&#xff0c;平台收到某三甲医院告警通知&#xff0c;显示核心业务CIS系统数据库tempdb实例日志文件剩余空间不足。 查看告警详情页&#xff0c;显示tempbd日志文件使用率在凌晨1:30后异常增高。 一个小tip tempdb是SQL Server实例的系统数据库&…

NC(65)元数据增加字段

以报销单主表er_bxzb表为例&#xff0c;增加15个字段字段以及两个其他业务所需字段 1、先在er_bxzb增加字段 增加字段 alter table er_bxzb add no_invoice char(1) default(N);alter table er_bxzb add is_enabled_taxation_cloud char(1) default(N);alter table er_bxzb a…

云服务器的优势

云服务器的优势 裸机云服务器&#xff0c;拥有物理机同样的性能和安全&#xff0c;也具有云主机的灵活和弹性。其最显著的优势在于&#xff0c;用户能够直接控制服务器及其资源&#xff0c;这一点与虚拟化云实例有明显区别&#xff0c;后者会将底层硬件操作对用户进行隐藏。此外…

《PySpark大数据分析实战》-20.NumPy介绍数组的生成

&#x1f4cb; 博主简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是wux_labs。&#x1f61c; 热衷于各种主流技术&#xff0c;热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员&#xff08;PCTA&#xff09;、TiDB数据库专家&#xff08;PCTP…

原来count(*)是接口性能差的真凶

前言 最近我在公司优化过几个慢查询接口的性能&#xff0c;总结了一些心得体会拿出来跟大家一起分享一下&#xff0c;希望对你会有所帮助。 我们使用的数据库是Mysql8&#xff0c;使用的存储引擎是Innodb。这次优化除了优化索引之外&#xff0c;更多的是在优化count(*)。 通…