C++11左值、右值

news2024/11/26 2:05:30

知识回顾,详解引用

简单概括,引用就是给已存在对象取别名,引用变量与其引用实体共用同一块内存空间

左右值区分

注意:不一定=左边的都是左值,=右边的都是右值

=左边的也可能是右值,等号右边的也可能是左值

int main()
{
	int a = 10;
	int b = 20;

	// a和b都是左值,b既可以在=的左侧,也可在右侧,
	// 说明:左值既可放在=的左侧,也可放在=的右侧
	a = b;
	b = a;

	const int c = 30;
	// 编译失败,c为const常量,只读不允许被修改
	//c = a;
	// 因为可以对c取地址,因此c严格来说不算是左值
	cout << &c << endl;

	// 编译失败:因为b+1返回的是一个临时变量,没有具体名称,也不能取地址,因此为右值
	//b + 1 = 20;
	//b+1会调用编译器自己的operator+这个函数,然后返回结果会返回一个临时对象
	return 0;
}

C++11对右值进行了严格的区分:

1.C语言中的纯右值,比如:a+b, 100,a+b返回的是一个临时对象,不能对该对象取地址,所以为右值

2.将亡值。比如:表达式的中间结果、函数按照值的方式进行返回。

3.const修饰的常量,不可修改,只读类型的,理论应该按照右值对待,但因为其可以取地址(如果只是 const类型常量的定义,编译器不给其开辟空间,如果对该常量取地址时,编译器才为其开辟空间), C++11认为其是左值。

右值引用

int main()
{
	//reference引用ra=reference_a
	int a = 1;
	int& ra1 = a;//=不表达赋值,仅表示将a变量所代表的空间重新起了一个ra的别名

	//cout << &1 << endl;//错误--提示表达式必须为左值
	//cout << &a << endl;//正确--区分&1,a是将1的值赋值给a,a已经开辟了空间,a为左值

	//1为右值(纯右值),不能对1取地址,简单理解为。
	//int& ra2 = 1;//没有地址就没有可操作空间没有空间就不能对该空间起别名
	
	//右值引用--&&
	//由于右值都没有具体空间,根据引用特性,对同一块空间取别名
	//我们必须创造一个空间,并将右值传递到该空间,才能使用右值引用
	int&& r1 = 1;//1赋值给一个临时空间,r1实际是对该临时空间的引用
	r1 = 2;//有了空间后就能修改
	cout << r1 << endl;
	
	//int&& r2 = a;//报错--无法将右值引用绑定到左值(右值引用不能引用左值)

	return 0;
}

const引用

int main()
{
	int a = 1;
	//const左值引用
	const int& ra1 = a;
	//const右值引用
	const int&& ra2 = 1;
	return 0;
}

const可以对右值引用也可以对左值引用

右值引用作用

C++11中右值引用主要有以下作用:

1. 实现移动语义(移动构造与移动赋值)

移动构造:

string& operator=(string&& s)
{
	swap(s);//对象里的变量和s(临时对象)内容交换后,将老版本内容随着s的生命周期的消失而delete
	return *this//返回对象
}

移动赋值:

String(String&& s)
	: _str(s._str)
{
	s._str = nullptr;
}

2. 给中间临时变量取别名(提高效率节省资源,对于开空间的自定义类)

左右值引用后修改值

int main()
{

	int a = 1;
	cout << "引用前a的值" << a << endl;
	//左值引用
	int& ra1 = a;
	ra1 = 2;
	cout << "引用修改后a的值" << ra1 << endl;

	//右值引用
	int&& ra2 = 1;
	cout << "引用前a的值" << ra2 << endl;
	ra2 = 3;
	cout << "引用修改后a的值" << ra2 << endl;
    //这里表明:右值(1)被右值引用(ra2)后的属性是左值ra2 = 3
	return 0;
}

为什么右值被右值引用后引用变量的属性是左值?

答:在被右值引用后会为右值创建一个临时变量≈创建了一个实际的存储空间。所以最后引用变量的属性是左值。

右值引用后引用变量的属性是左值

class String
{
public:
	//有参构造
	String(const char* str = "")
	{
		if (nullptr == str)
			str = "";
		_str = new char[strlen(str) + 1];
		strcpy(_str, str);
	}
	//拷贝构造
	String(const String& s)
		: _str(new char[strlen(s._str) + 1])
	{
		strcpy(_str, s._str);
	}

	//嵌套多个函数模拟实验右值在传递后的属性
	String copy(const String& s)
	{
		_str = new char[strlen(s._str) + 1];
		strcpy(_str, s._str);
		cout << "传递来的str_left_value为左值" << endl;
		return *this;
	}

	void class_copy(String&& str_left_value)//str_left_value记为str1
	{
		copy(str_left_value);//str_left_value记为str2
	}
	//移动语义-移动构造
	String(String&& s)
		: _str(s._str)
	{
		s._str = nullptr;
	}

	~String()
	{
		if (_str) delete[] _str;
	}
private:
	char* _str;
};

int main()
{
	String str;
	str.class_copy("abc");

	return 0;
}

图解:

因为此时还是对数组类型进行操作,不断的复制已有内容会造成资源的浪费,我们依旧还想用右值引用来减少浪费

class String
{
public:
	//有参构造
	String(const char* str = "")
	{
		if (nullptr == str)
			str = "";
		_str = new char[strlen(str) + 1];
		strcpy(_str, str);
	}
	//拷贝构造
	String(const String& s)
		: _str(new char[strlen(s._str) + 1])
	{
		strcpy(_str, s._str);
	}

	//仅测试

	void copy(String& s)
	{
		cout << "传递来的str_left_value为左值" << endl;
	}
	void copy(String&& s)
	{
		cout << "传递来的str_left_value为右值" << endl;
	}

	//右值引用后继续使用右值
	void class_copy(String&& str_left_value)
	{
		copy(move(str_left_value));
	}

	//移动语义-移动构造
	String(String&& s)
		: _str(s._str)
	{
		s._str = nullptr;
	}

	~String()
	{
		if (_str) delete[] _str;
	}
private:
	char* _str;
};

int main()
{
	String str;
	str.class_copy("abc");

	return 0;
}

此时只要我们将右值引用后引用变量的属性是左值让其move后转变成右值就可以继续使用右值引用

注意:为了避免const修饰右值引用导致资源无法转移,在以后使用右值引用转移资源时应避免或禁止使用const

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

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

相关文章

大数据工程师如何做到数据可视化?

好的数据可视化作品都是通过不断的数据对比分析实战出来的。 今天给大家带来一篇大数据工程师干货&#xff0c;从多角度解析做数据可视化的重要性&#xff0c;并解读一些适用的应用场景。大数据工程师们刷到这篇文章时一定要进来看看&#xff0c;满满的干货。 目录 1. 什么是数…

中望CAD 2025 (ZW3D2025) 简体中文修改版

名称&#xff1a;中望CAD 2025 (ZW3D2025) 简体中文修改版 描述&#xff1a;一款三维CAD设计工具&#xff0c;运行破解补丁ZW3D2025-2024-Patch执行修补。 链接&#xff1a;夸克网盘分享 &#x1f4c1; 大小&#xff1a;3.2GB &#x1f3f7; 标签&#xff1a;#PC软件 #CAD #设…

为什么笔记本电脑触控板不工作?这里有你想要的答案和解决办法

序言 你的笔记本电脑触控板停止工作了吗?值得庆幸的是,这个令人沮丧的问题通常很容易解决。以下是笔记本电脑触控板问题的最常见原因和修复方法。 触控板被功能键禁用 大多数(如果不是全部的话)Windows笔记本电脑都将其中一个功能键用于禁用和启用笔记本电脑触控板。按键…

【Arthas案例】某应用依赖两个GAV不同但包含两个相同全限定类名StaticLoggerBinder,引起log4j.Level类找不到异常

3分钟内解决问题 两个不同的GAV依赖冲突&#xff0c;包含相同全限定类名&#xff0c;引起ClassNotFoundException Maven依赖的三坐标体系GAV(G-groupId&#xff0c;A-artifactId&#xff0c;V-version) 【案例1】某应用依赖两个GAV不同的jar&#xff0c;但包含两个相同全限定类…

Jmeter多个请求按照比例并发压测的几种方式

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、需求 在压测的过程中&#xff0c;为了能够压测整个链路&#xff0c;通常需要多个接口进行并…

OpenAI Assistants API:如何使用代码或无需代码创建您自己的AI助手

Its now easier than ever to create your own AI Assistant that can handle a lot of computing tasks for you. See how you can get started with the OpenAI AI Assistant API. 现在比以往任何时候都更容易创建您自己的AI助手&#xff0c;它可以为您处理许多计算任务。了…

微信公众号打通与登录的实现

今天实现一下与微信公众号进行对接&#xff0c;通过扫描二维码的方式来进行注册与登录&#xff0c;获取用户的微信唯一标识作为用户的username&#xff0c;下面我们开始编写。 骨架建立&#xff1a; 建包&#xff1a; 第一步还是先将骨架建好&#xff0c;与网关骨架差不多&a…

树莓派4B_OpenCv学习笔记9:图片的腐蚀与膨胀

今日继续学习树莓派4B 4G&#xff1a;&#xff08;Raspberry Pi&#xff0c;简称RPi或RasPi&#xff09; 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: Opencv 版本是4.5.1&#xff1a; 图像的膨胀与腐蚀一般用于灰度图或者二值图,今日便来学习…

基于python-CNN卷积网络训练识别牛油果和猕猴桃-含数据集+pyqt界面

代码下载地址&#xff1a; https://download.csdn.net/download/qq_34904125/89383066 本代码是基于python pytorch环境安装的。 下载本代码后&#xff0c;有个requirement.txt文本&#xff0c;里面介绍了如何安装环境&#xff0c;环境需要自行配置。 或可直接参考下面博文…

目前市面上DIY高端空心耳机壳使用的透明原材料是什么?

目前市面上DIY高端空心耳机壳使用的透明原材料是什么&#xff1f; DIY制作耳机壳的UV树脂胶是一种单组份、通过紫外线光固化的胶粘剂&#xff0c;具有低能量固化、收缩低、发热量低、高透明、耐盐酸、耐黄变好、高硬度、韧性好、成型好等特点。这种胶粘剂非常适合用于制作耳机壳…

Redis 主从集群 哨兵原理

一. Redis 主从集群 1.1 基本概念 主从架构&#xff1a;Redis主从集群采用“一主多从”的架构模式&#xff0c;其中主节点&#xff08;Master&#xff09;负责处理客户端的读写请求&#xff0c;而从节点&#xff08;Slave&#xff09;则负责处理读请求。这种读写分离的设计使…

Pytest 读取excel文件参数化应用

本文是基于Pytest框架&#xff0c;读取excel中的文件&#xff0c;传入页面表单中&#xff0c;并做相应的断言实现。 1、编辑媒体需求 首先明确一下需求&#xff0c;我们需要对媒体的表单数据进行编辑&#xff0c;步骤如下&#xff1a; 具体表单如下图所示 1、登录 2、点击我…

618洗地机全网热门推荐,跟着买错不了

步入酷热夏天&#xff0c;家中的清洁工作也迎来了新的挑战。天气炎热&#xff0c;细菌、异味滋生的困扰让日常打扫变得不再轻松&#xff0c;这时一台高性能的洗地机就成了提升生活品质的必备良品。不同于洗地机的技术与类别繁多&#xff0c;洗地机虽原理不复杂&#xff0c;但在…

堆栈溢出的攻击 -fno-stack-protector stack smash 检测

在程序返回的一条语句堆栈项目处&#xff0c;用新函数的起始地址覆盖&#xff0c;将会跳转到执行新函数。 现在系统对这个行为做了判断&#xff0c;已经无法实施这类攻击或技巧。 1&#xff0c;测试代码 #include <stdio.h> void cc() {printf("I am cc( )\n"…

【AI+编程】工作日常场景随时可以AI编程,记一个问答SQL快速导出数据日常示例

今天有个场景&#xff0c;我们有个老项目&#xff0c;由于历史原因差不多1年多没使用了&#xff0c;恰巧客户紧急情况要使用。因为当时没有需求&#xff0c;所以V1.0上线后 就没做更新。 需求很简单&#xff1a;我们假定 项目问题表、客户表、问题答案表&#xff0c; 实时查询…

VisionOS的未来愿景:苹果VisionPro创业者的愿望清单

随着苹果公司在增强现实(AR)领域的不断探索,VisionPro作为其前沿产品,已经开始展现出改变我们与数字世界互动方式的潜力。作为一名VisionPro创业者,对未来VisionOS的更新充满了期待,并提出了一系列愿望清单,这些愿望不仅代表了个人的需求,也反映了用户社区对苹果AR生态的…

【ETAS CP AUTOSAR基础软件】DET、Bfx、CRC、ComStack、rba_ArxmlGen模块详解

文章包含了AUTOSAR基础软件&#xff08;BSW&#xff09;中DET、Bfx、CRC、ComStack、rba_ArxmlGen模块相关的内容详解。本文从AUTOSAR规范解析&#xff0c;ISOLAR-AB配置以及模块相关代码分析三个维度来帮读者清晰的认识和了解DET、Bfx、CRC、ComStack、rba_ArxmlGen。文中涉及…

logTrick

贴一下灵神的题解里面的解释~ 就是一种优化策略&#xff0c;logtrick class Solution { public:int minimumDifference(vector<int>& nums, int k) {int res 0x3f3f3f3f;int n nums.size();for(int i0;i<n;i){res min(res,abs(nums[i]-k));for(int j i-1;j&g…

2024年6月15日 (周六) 叶子游戏新闻

期刊杂志: 聚合读者、意林、知音、故事会、花火以及国内各大知名报纸电子版&#xff0c;无需付费即可观看各种免费资源 中医自学宝典: 集合了中医医案&#xff0c;医经&#xff0c;方剂 药材知识的app&#xff0c;更方便的免费学习中医知识 《赛博朋克2077》被取消DLC泄露&…

20240615在WIN11下的串口调试助手的下载安装以及使用

20240615在WIN11下的串口调试助手的下载安装以及使用 2024/6/15 18:06 百度&#xff1a;串口调试助手 blob:https://apps.microsoft.com/df934d29-fd7a-4873-bb6b-a4ab5a7934c9 串口调试助手 Installer.exe 收发的LOG&#xff1a; rootok3588:/# ./uart_test /dev/ttyS0 11520…