C++左值引用与右值引用

news2025/2/26 6:19:42

0.类型和值类别的区别?

类型(type)和值类别(value category)

1.类型指的是数据类型,int,char这样的内置类型,类型主要是用来区别它们的字节大小。除了内置类型还有自定义类型,自定义类型中的类型还表征了结构,像C语言的结构体,由于结构(或者说内置类型的顺序)的不同引发的内存对齐问题。所以类型表征的是大小,结构。

2.值类别呢,就是关于变量的左右值属性

1.如何区分左值右值?

1.从高级语言的角度--能否被引用

如果能取地址,说明这个变量是左值,我们可以通过地址修改它,如果不能取地址,则变量是右值,我们不能通过地址修改它。

比如int num = 10;

将10存储到变量num中,num对应一个地址,后续可以通过地址修改num的值,所以我们称num为左值(num在表达式的左边,这是左的含义),表达式右边的10就是一个右值,我们无法通过10的地址修改10。

2.从高级语言的角度--值类别表征了数据的存储位置

从计算机体系结构的角度理解

int num = 10;

全新的理解是:num不是什么变量名,num对应了一个地址,是位于进程地址空间上的栈区的地址,int也不是什么类型,int表示从该地址往后8字节的空间被进程使用了,要以8字节为一个整体,修改该地址上的内容。

而10是一个字面常量,用二进制表示为00001010,根据赋值对象的不同再进行提升或截断,比如10要赋值给int对象,所以被提升为00000000 ... 00001010(前面多出7个全0的序列,每个序列有8个0),存储时再根据大小端字节序将这些字面值从代码区拷贝到刚才的栈区地址上。

这行代码被编译后会被放到进程地址空间的正文代码区,系统怎么知道你要用10初始化num?因为正文代码区的存储了10的二进制序列,代码区中还有10要放入的地址(没有什么num,只有一串地址),以及把10放到地址上的指令,这些信息都会在代码中表示。并且,程序的正文代码区也是有地址的,代码区存储系统要执行的指令。现在回头看右值的概念,不能取地址的就是右值,10有地址吗?当然有,没有地址系统怎么访问正文代码区,怎么知道你要初始化的值是10,所以不能取地址不是因为没有地址,而是因为这个地址你不能知道,地址位于只读数据区(代码区的数据可不能随便修改,当然是只读数据区)或者说该地址上的数据只有在程序运行后才会被系统读取,你要取地址,编译器直接出手,谁能保证你不会做一些危害系统安全的事,编译器可不会给你这些地址,于是程序编译失败。

总结:我认为只要数据位于的区域你没有权限访问,这些数据就是右值,你有权限访问的区域,存储的数据是左值。

2.将亡值

我们通常讨论的左值并不是gvalue(泛左值),而是lvalue,通常讨论的右值是rvalue,它包含了将亡值xvalue和纯右值pvalue,其中的将亡值与右值引用息息相关,匿名对象和函数返回值都是将亡值,它们都具有常属性,并且生命周期较短,在下一条语句执行前资源就会被释放。具体的比如隐式类型转换产生的中间变量,为了调用类的函数而定义的匿名对象,这些变量似乎都是工具人,被创建只是为了其他语句的成功执行

实例

左值

int x = 8;
int & func()
{
    return x;	//不能将临时变量以左值返回,这里返回个全局变量的引用
}
 
func() = 10;	//func()返回的是左值,可以放在左边被赋值
printf("x = %d", x);	//10。修改的其实是x

右值

int func()
{
    int x = 9;
    return x;
}
 
func() = 10;	//编译器报错
//你只能:
int y = func();	//func()返回的其实是临时变量,也就是右值,然后将这个右值赋给y(逻辑上可以这样理解没问题,编译器不一定按这个步骤来,请看示例二)

3.C++11右值引用

右值引用是右值吗 :右值引用不是右值,它是一个左值;

1.C++11右值分类

C++11中的右值可以分为两种:

1.纯右值:内置类型表达式的值

2.将亡值:自定义类型表达式的值:所谓的将亡值就是指声明周期马上就要结束 的值,一般来说匿名对象,临时对象,move后的自定义类型都可以看做将亡值、

2.左值引用与右值引用区别

左值引用:左值引用只能引用左值,不能引用右值。但是const左值引用既可引用左值,也可引用右值,因为 const左值引用也是只读的,而权限可以平移

int main()
{
	// 左值引用只能引用左值,不能引用右值。
	int a = 10;
	int& ra1 = a;    // ra为a的别名
	//int& ra2 = 10;   // 编译失败,因为10是右值
	
	// const左值引用既可引用左值,也可引用右值。
	const int& ra3 = 10;
	const int& ra4 = a;
	return 0;
}

右值引用只能右值,不能引用左值,但是右值引用可以move以后的左值。

int main()
{
	// 右值引用只能右值,不能引用左值。
	int&& r1 = 10;

	// error C2440: “初始化”: 无法从“int”转换为“int &&”
	// message : 无法将左值绑定到右值引用
	//int a = 10;
	//int&& r2 = a;

	// 右值引用可以引用move以后的左值
	int&& r3 = std::move(a);
	return 0;
}

2.右值引用的作用

 右值引用是C++11新特性,之所以引入右值引用,是为了提高效率。如下面所示:

class A
{
public:
	A(size_t N):m_p(new char[N])
	{
	}
	A(const A & a)
	{
		if (this != &a)
		{
			delete[]m_p;
			m_p = new char[strlen(m_p) + 1];
			memcpy(m_p, a.m_p, strlen(m_p) + 1);
		}
	}
	~A()
	{
		delete []m_p;
	}
 
private:
	char *m_p = nullptr;
};
 
A createA(size_t N)
{
	return A(100);
}
 
void func(A a)
{
	//
}
 
int main()
{
	func(createA(100));
 
	system("pause");
	return 0;
}

在查阅过程中发现一片讲的较为透彻的文章 ,想了解更具体的可以查看C++ / 左值、右值、将亡值 | 谈谈我对它们的深入理解 - 知乎 (zhihu.com)

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

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

相关文章

前端构建但没有更新

使用jenkins构建vue前端代码时,构建完成后,jenkins提示构建成功, 但前端刷新提示还是原来的效果,此时需要查看下jenkins构建日志,如果出现下面的文字,说明缺少依赖,最新的代码并没有构建到项目中…

QT-opengl编译错误

问题1: QT编译错误:undefined reference to __imp_gl* 解决方案 在工程*.pro文件中加入 win32:LIBS -lOpengl32 \-lglu32 win32-msvc{LIBS opengl32.lib \glu32.lib \glut.lib}问题2: 解决方案: 改变变量名称: 改…

WebSocket—STOMP详解(官方原版)

WebSocket协议定义了两种类型的消息(文本和二进制),但其内容未作定义。该协议定义了一种机制,供客户端和服务器协商在WebSocket之上使用的子协议(即更高级别的消息传递协议),以定义各自可以发送…

VM虚拟机 13.5 for Mac

VMware Fusion Pro for Mac是一款强大的虚拟机软件,可以在Mac操作系统中创建、运行和管理多个虚拟机,使用户可以在一台Mac电脑上同时运行多个操作系统和应用程序。 以下是VMware Fusion Pro for Mac的主要特点: 1. 支持多种操作系统&#xff…

CC攻击演示

选择一个代参数网站 未攻击前的cpu 用工具进行CC攻击 执行攻击会把目标主机占用内存,可以在把次数加大一点

(十二)Python文件操作(I/O)

和其它编程语言一样,Python 也具有操作文件(I/O)的能力,比如打开文件、读取和追加数据、插入和删除数据、关闭文件、删除文件等。 除了提供文件操作基本的函数之外,Python 还提供了很多模块,例如 fileinpu…

前端学成在线项目详细解析三

19-推荐课程-内容样式 HTML结构 <ul><li><a href"#"><div class"pic"><img src"./uploads/course01.png" alt""></div><div class"text"><h4>JavaScript数据看板项目实战…

旋转数组的最小值

文章目录 1 题目2 思路2.1 思路12.2 思路2 3 实现3.1 暴力3.2 二分查找 1 题目 将一个数组最开始的若干元素搬到数组的末尾&#xff0c;称之为数组的旋转。输入一个已排好序数组的一个旋转&#xff0c;求该旋转数组的最小元素。如&#xff0c;数组{3&#xff0c;4&#xff0c;…

linux文件存储之inode,硬链接,软链接详解

1.什么是inode 首先linux一切皆文件&#xff0c;一切皆文本流 inode &#xff0c;中文译名“索引节点”&#xff0c;也叫“i节点” 文件储存在硬盘上&#xff0c;硬盘的最小存储单位叫做”扇区”&#xff08;Sector&#xff09;。每个扇区储存512字节&#xff08;相当于0.5KB&a…

基于Java的校园餐厅订餐管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09; 代码参考数据库参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…

塔望3W消费战略全案丨轻食植物基,突围侧翼战

植鲜生 客户&#xff1a;民强&#xff08;昆山&#xff09;食品科技有限公司 品牌&#xff1a;植鲜生 时间&#xff1a;2021年起 项目部分内容保密期 突破传统植物基禁锢 破局轻食新赛道 民强&#xff08;昆山&#xff09;食品科技有限公司是一家集研发、生产、销售为一体…

详细讲解MySQL中的数据类型

详细讲解MySQL中的数据类型 一&#xff0c;整数类型 MySQL中常用的整数类型包括&#xff1a; TINYINT&#xff1a;占用1字节&#xff0c;表示范围为-128到127的有符号整数或0到255的无符号整数。 SMALLINT&#xff1a;占用2字节&#xff0c;表示范围为-32768到32767的有符号整…

众佰诚:开抖音小店需要交保证金吗

随着互联网的发展&#xff0c;越来越多的人选择通过开设网店来创业。抖音作为一款短视频平台&#xff0c;也提供了开店的功能。那么&#xff0c;开抖音小店需要交保证金吗?这是许多创业者关心的问题。 首先&#xff0c;我们需要明确的是&#xff0c;开设抖音小店是需要交纳保证…

【TensorFlow1.X】系列学习笔记【入门四】

【TensorFlow1.X】系列学习笔记【入门四】 大量经典论文的算法均采用 TF 1.x 实现, 为了阅读方便, 同时加深对实现细节的理解, 需要 TF 1.x 的知识 【TensorFlow1.X】系列学习文章目录 文章目录 【TensorFlow1.X】系列学习笔记【入门四】前言损失函数作用均方误差(MSE)交叉熵(C…

智能医疗:互联网医院开发的挑战与机会

随着技术的不断进步&#xff0c;互联网医院的发展为医疗保健带来了巨大的机遇&#xff0c;但同时也带来了一系列挑战。本文将探讨互联网医院开发中的一些关键挑战和机会&#xff0c;以及如何应对这些挑战。 挑战一&#xff1a;数据隐私和安全性 在互联网医院开发中&#xff…

Kubernetes技术与架构-网络 2

Kubernetes集群支持IP地址以及DNS访问Pod或者Service。 Service域名解析 Service域名解析包括A/AAAA记录以及SRV记录 A/AAAA记录 域名&#xff1a;my-svc.my-namespace.svc.cluster-domain.example 该域名对应的service名称是my-svc、service的命名空间是my-namespace、servic…

Qt之自定义model读写CSV文件

一.效果 本文基于QAbstractTableModel实现了一个支持读写CSV文件的TableModel。CSV数据格式虽然很简单,但是网上大多数读写方式其实都是有bug的,没考虑到字段里包含逗号或换行符这种复杂数据的情况。 二.原理 CSV(Comma-Separated Values)文件是一种简单类型的纯文本文件…

GoLong的学习之路(三)语法之运算符

书接上回&#xff0c;我们进展到了GoLong的基本数据类型&#xff0c;接下来说运算符&#xff08;其实和常见的编程语言的逻辑规则一样&#xff09; 运算符 运算符用于在程序运行时执行数学或逻辑运算。&#xff08;不可谓不重要&#xff09; Go 语言内置的运算符有&#xff…

python基础语法(4)

基础语法 前言文件文件是什么文件路径文件操作1.打开文件2. 关闭文件3.写文件4. 读文件5.上下文管理器 库使用库标准库第三方库 前言 本文基于pycharm编译器&#xff0c;也可以使用Anaconda 里的编译器&#xff0c;将讲解一些python的一些基础语法知识&#xff0c;是对上篇文章…

element-ui的日历组件el-calendar高度咋调小

最近项目首页有个空余 不知道放啥 打算放个日历card 充充位置&#xff0c; el-calendar日历组件的整体宽度可以用el-row el-col :gutter :span来控制自适应 但是官网文档没说高度咋缩小 细长一条好难看 自己尝试改了改element的样式没整出来 最后照着这位博主的方法改是好使滴…