C++内功修炼干货,进大厂必须会的C++左值与右值,最适合小白看的文章!

C++内功修炼----基础知识的零碎整理 c和c++的区别? 第一点就应该想到C是面向过程的语言,而C++是面向对象的语言,一般简历上第一条都是熟悉C/C++基本语法,了解C++面向对象思想,那么,请问什么是面向对象? C和C++动态管理内存的方法不一样,C是使用malloc/free函数,而C++除此之外还有new/delete关键字;(关于malooc/free与new/delete的不同又可以说一大堆,最后的扩展_1部分列出十大... 阅读详情


左值和右值是C++比较重要也比较复杂的知识点,可能学习C++很久的人对这俩个概念都不是很熟悉!我在大学中对他们也是没有概念,最近学到这里,发现网上对这俩的解释也千奇百怪,所以经过三天的学习和整理,整理出一份还不错的笔记,建议大家重点看这一篇,不要被其他文章带跑偏了。

在这里插入图片描述

左值和右值的定义

在C++11中所有的值必属于左值、右值两者之一。右值又可以细分为纯右值、将亡值。在C++11中可以取地址的、有名字的就是左值,反之,不能取地址的、没有名字的就是右值(将亡值或纯右值)。
举个例子,int a = b + c,a 就是左值,其有变量名为a,通过&a可以获取该变量的地址;表达式b+c、函数int func()的返回值就是右值,在其被赋值给某一变量前,我们不能通过变量名找到它,&(b+c)这样的操作则不会通过编译。

左值

左值与右值这两概念是从 c 中传承而来的,在 c 中,左值指的是既能够出现在等号左边也能出现在等号右边的变量(或表达式)

右值

右值指的则是只能出现在等号右边的变量(或表达式).

扩展

在这里插入图片描述

在理解C++11的右值前,先看看C++98中右值的概念:C++98中右值是纯右值,纯右值指的是临时变量值、不跟对象关联的字面量值。临时变量指的是非引用返回的函数返回值、表达式等,例如函数int func()的返回值,表达式a+b;不跟对象关联的字面量值,例如true,2,”C”等。
C++11对C++98中的右值进行了扩充。 在C++11中右值又分为纯右值(prvalue,Pure Rvalue)和将亡值(xvalue,eXpiring Value)。其中纯右值的概念等同于我们在C++98标准中右值的概念,指的是临时变量和不跟对象关联的字面量值;将亡值则是C++11新增的跟右值引用相关的表达式,这样表达式通常是将要被移动的对象(移为他用),比如返回右值引用T&&的函数返回值、std::move的返回值,或者转换为T&&的类型转换函数的返回值。
将亡值可以理解为通过“盗取”其他变量内存空间的方式获取到的值。在确保其他变量不再被使用、或即将被销毁时,通过“盗取”的方式可以避免内存空间的释放和分配,能够延长变量值的生命期。(通过右值引用来续命)

左值引用和右值引用

首先在C++11之前,只有左值引用,在C++11之后,才有右值引用。
我们学习右值引用之前,一定要带着问题去学习去思考,“引入一种额外的引用类型当然增加了语言的复杂性,但是我们为什么要增加复杂性呢,肯定同时也会带来优越性!”

概念

左值引用就是对一个左值进行引用的类型。右值引用就是对一个右值进行引用的类型,事实上,由于右值通常不具有名字,我们也只能通过引用的方式找到它的存在。
右值引用和左值引用都是属于引用类型。无论是声明一个左值引用还是右值引用,都必须立即进行初始化。而其原因可以理解为是引用类型本身自己并不拥有所绑定对象的内存,只是该对象的一个别名。左值引用是具名变量值的别名,而右值引用则是不具名(匿名)变量的别名。
首先我们明确了最普通的左右值引用是:
左值引用:对一个左值进行引用
右值引用:对一个右值进行引用【C++11之后才引入右值引用】
那么还有没有一些特殊的引用呢?答案是有的!

左值引用绑定右值

关于右值,在 c++11 以前有一个十分值得关注的语言的特性:右值能被 const 类型的引用所指向,所以如下代码是合法的。

const cs& ref = get_cs();

而且准确地说,右值只能被 const 类型的 reference 所指向,非 const 的引用则是非法的:

1. // error 
2. cs& ref = get_cs();

注意:常量左值引用是个“万能”的引用类型。它可以接受非常量左值、常量左值、右值对其进行初始化。不过常量左值所引用的右值在它的“余生”中只能是只读的。相对地,非常量左值只能接受非常量左值对其进行初始化。

int &a = 2;       # 左值引用绑定到右值,编译失败
 
 int b = 2;        # 非常量左值
 const int &c = b; # 常量左值引用绑定到非常量左值,编译通过
 const int d = 2;  # 常量左值
 const int &e = c; # 常量左值引用绑定到常量左值,编译通过
 const int &b =2;  # 常量左值引用绑定到右值,编译通过

右值引用绑定左值

右值值引用通常不能绑定到任何的左值,要想绑定一个左值到右值引用,通常需要std::move()将左值强制转换为右值,例如:

int a;
int &&r1 = a;             # 编译失败
int &&r2 = std::move(a);  # 编译通过
int &&r2 = 2;  # 编译通过

实例

#include <iostream>
void process_value(int& i)
{
    std::cout << "LValue processed: " << i << std::endl;
}
void process_value(int&& i)     //右值引用
{
    std::cout << "RValue processed: " << i << std::endl;
}
int main()
{
    int a = 0;
    process_value(a);
    process_value(1);
}

我们在main函数中,非常正常地传入了一个左值和一个右值,所以输出结果也是正确的!
在这里插入图片描述

给右值引用传入一个左值

问题的来源:
r2是一个右值引用,但是r2本身是不是左值呢?C++11对此做出了区分:
如果它有一个名字,那么它是一个左值。否则,它是一个右值。

int main() 
 { 
   int a = 0; 
   process_value(a);
   int&& x = 3;
   process_value(x); 
 }

x 是一个右值引用,指向一个右值3,但是由于x是有名字的,所以x在这里被视为一个左值,所以在函数重载的时候选择为第一个函数。

在这里插入图片描述

右值引用的意义 我们如果想在实际开发中用到右值引用,我们就要搞清楚为什么我们需要右值引用,也就是右值引用的意义! 直观意义 为临时变量续命,也就是为右值续命,因为右值在表达式结束后就消亡了,如果想继续使用右值,那就会动用昂贵的拷贝构造函数。

这里引出了临时变量:

临时变量

C++ 中的临时变量指的是那些由编译器根据需要在栈上产生的,没有名字的变量。主要的用途主要有两类:

  1. 函数的返回值,
  2. 类型转换时的中间变量
    一般来说,C++ 中的临时变量在表达式结束之后 (full expression) 就被会销毁,但也有例外的时候,如果这个临时变量被用来初始化一个引用的话,那这个临时变量的生命周期就会被延长,直到引用被销毁,从而不会因此产生悬空(dangling)的引用。
    也就是说,一旦一个临时变量被引用,它的生命周期就变得和引用它的变量一样长!

右值引用是用来支持转移语义的。
转移语义可以将资源 ( 堆,系统对象等 ) 从一个对象转移到另一个对象,这样能够减少不必要的临时对象的创建、拷贝以及销毁,能够大幅度提高C++应用程序的性能。临时对象的维护 ( 创建和销毁 ) 对性能有严重影响。
转移语义是和拷贝语义相对的,可以类比文件的剪切与拷贝,当我们将文件从一个目录拷贝到另一个目录时,速度比剪切慢很多。通过转移语义,临时对象中的资源能够转移其它的对象里。
在现有的 C++ 机制中,我们可以定义拷贝构造函数和赋值函数。要实现转移语义,需要定义转移构造函数,还可以定义转移赋值操作符。对于右值的拷贝和赋值会调用转移构造函数和转移赋值操作符。如果转移构造函数和转移拷贝操作符没有定义,那么就遵循现有的机制,拷贝构造函数和赋值操作符会被调用。 普通的函数和操作符也可以利用右值引用操作符实现转移语义。

参考资料

【1】https://www.cnblogs.com/catch/p/3500678.html
【2】https://mp.weixin.qq.com/s?src=11&timestamp=1626703408&ver=3200&signature=-8fSD48eWwkkMchC3DjpghdBHkf4GySAjvEFSs1PsiwZfOP11nqAzk6XszTE9XQXFkGp7OP5G1gLLAmAehwOlqpw8yMwA0X3FMKfMrwzQE4-HrKQHSgAbIYDp6s-OP&new=1
【3】临时变量:https://www.cnblogs.com/catch/p/3251937.html
【4】牛逼:http://c.biancheng.net/view/7847.html

写作不易,希望给个关注,有问题可以随时私聊交流
在这里插入图片描述

C++11 中的左值、右值和将亡值 来源:georgeguoC++98 中表达式值的类型只有左值和右值两种类型,可以取到地址的表达式就是左值,不是左值的值就是右值,而C++11中将表达式的值类型划分成了lvalue(左值)... 阅读详情

相关推荐

Dynamics 365 F&O新手必看:Visual Studio 2019搭建项目框架全流程(含Model避坑指南)

本文详细介绍了如何在Visual Studio 2019中为Dynamics 365 Finance and Operations搭建企业级项目框架,包括Model分层策略、Solution管理及开发工作流优化。特别提供了Model避坑指南和实用配置建议,帮助新手快速上手并避免常见错误。

weixin_30505225的博客 382

【C/C++内功心法】剖析预处理过程,详解预处理指令,提升C/C++内功

今天我将会为大家详细讲解预处理指令。虽然本文章读完后不能让大家代码写得飞起,但是预处理这个过程是十分重要的,其中的很多指令也是经常被考到,你了解了它,它将会大幅提升你的C/C++内功,让你学编程更加的容易。

这是一个非常有意思的博主 4686

Vivado SDK中LWIP库版本冲突与RTL8211FDI兼容性实战解析

本文深入解析Vivado 2019.1 SDK中LWIP 1.0库与RTL8211FDI千兆PHY芯片的版本冲突问题,并提供实战解决方案。通过手动移植高版本LWIP库、整合第三方驱动及优化BSP配置,有效解决了以太网通信兼容性问题,确保千兆性能稳定运行。

ios99的博客 275

关于左值右值的定义

左值: 指向内存的位置(可以看作是指针类型变量) 右值: 是存储在内存中某些地址的数值,是不可被改变的常量

qq_42807221的博客 192

让 PyCharm 代码“发光”:高亮插件与特效全攻略

PyCharm 作为一款强大的 Python IDE,支持多种插件让代码“发光”——无论是动态输入特效、彩虹括号,还是霓虹主题,都能让你的代码脱颖而出!进入 File → Settings → Editor → Color Scheme → Rainbow Brackets。进入 File → Settings → Appearance & Behavior → Material Theme。进入 File → Settings → Editor → Color Scheme → General。

qq_43580271的博客 3838

TC3XX - MCAL知识点(一):新建Tc3xx EB-tresos工程

基于EB-tresos建立Hightec或者Tasking工程的时候,第一个步骤就是需要新建一个EB-tresos的工程,本文记录一下如何新建一个EB-tresos工程,以及对其进行简单的操作。那么Tc3xx的MCAL包含哪些内容呢?

梦想技术家 2974

【C++语言】深入学习C++要修炼的内功

函数栈帧是在内存中的栈区为被调函数开辟的一块空间,里面存放的是该函数中定义的变量等东西,当函数运行完毕栈帧将会被销毁。Push:入栈,为栈增加一个元素Pop:出栈,从栈中取出栈顶。

加油,考上985的研究生 1281

PyTorch实战(19)——变分自编码器(Variational Autoencoder,VAE)

变分自编码器 (Variational Autoencoder, VAE) 是一种结合了自编码器和概率建模的生成模型,通过编码器将输入数据映射到潜在空间中的概率分布,并通过解码器将从潜在空间采样得到的潜在变量映射回原始数据空间,实现了数据的生成和特征学习。本节中,将介绍变分自编码器的基本概念,并使用 PyTorch 实现变分自编码器生成新图像。

盼小辉丶的博客 2919

菜鸟程序员内功心法--C++(核心编程)

本文为C++面向对象编程技术的个人学习笔记,仅供记录学习使用

举个栗子的博客 1490

大数据学习指南从入门到精通

利用框架的力量,看懂游戏规则,才是入行的前提大多数人不懂,不会,不做,才是你的机会,你得行动,不能畏首畏尾选择才是拉差距关键,风向,比你流的汗水重要一万倍,逆风划船要累死人的为什么选择学习大数据开发,不选择Java开发?借棋弈做比喻,智商高的不要选择五子琪,要选择围棋,它能长久地吸引你。不都是在棋盘上一颗黑子一颗白子地下吗?因为围棋更复杂,能够掌握如此复杂的技艺、产生稳定输出的棋手、让我们更佩服。选择学习大数据开发也如此,能让你的职业生涯走得更远,少走弯路。

Lansonli(蓝深李)的博客 2万+

我正用AI Agent重构传统GIS 核心功能,说大白话做空间分析

GeoAI-UP项目通过AI Agent技术实现自然语言驱动的空间分析,核心创新包括: 意图识别层:通过LLM理解用户需求,自动拆解为可执行目标 智能任务规划:动态生成分析流程,处理复杂依赖关系 统一算子架构:采用标准化接口封装200+空间分析功能 可视化工作流。

专注GIS软件开发。 496

C++内功修炼----类型

Table of Contents 0.概述 1.基本类型 1.1 引用 1.1.1 引用的原理 1.1.2引用的注意点 1.1.3 引用的分类 1.2指针 1.2.1指针的原理 1.2.2指针与引用 1.2.3指针与数组 1.2.4指针与函数 1.2.5野指针 ...

vjhghjghj的博客 590

Python控制TEMI1000/TEMI1500测试温箱

该温箱是我司从昆山振弘检测设备有限公司采购的TEMI 1000,但是控制器用的是韩国的,关于控温箱这个项目,可参考的资料仅有一份官方的manual,里面包含一些命令格式。只要你有温箱,就应该可以向厂家索取该文档。该温箱的通讯接口只有一个RS232接口,要想实现远程控制,需要有串口转USB的线;类似于下图所以,想依靠python来与之进行通信,还是要通过python 的pyserial库,关于怎么安装pyserial,过于简单,这里不做赘述,可自行百度。

xgh1951的博客 1万+

Android开发者们跳槽面试,一定要看看这篇文章啊!(1),2024年最新这是一份面向Android开发者的复习指南

说一千道一万,不如自己去行动。要想在移动互联网的下半场是自己占有一席之地,那就得从现在开始,从今天开始,马上严格要求自己,既重视业务实现能力,也重视基础和原理。基础夯实好了,高楼才能够平地而起,稳如泰山。最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2020-2021面试真题解析,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。还有。

2401_84103616的博客 432

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

C++内功修炼----预处理 volatile

1.预处理 1.1define 宏定义和函数有何区别? 宏在编译时完成替换,之后被替换的文本参与编译,相当于直接插入了代码,运行时不存在函数调用,执行起来更快;函数调用在运行时需要跳转到具体调用函数。 宏函数属于在结构中插入代码,没有返回值;函数调用具有返回值。 宏函数参数没有类型,不进行类型检查;函数参数具有类型,需要检查类型。 宏函数不要在最后加分号。 宏定义和const...

vjhghjghj的博客 322

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

面向对象的三个基本特征

面向对象的三个基本特征是:封装、继承、多态。 [img]http://www.cnitblog.com/images/cnitblog_com/lily/1972/o_OOBase.gif[/img] 封装 封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的...

Tears of a poet 2807

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

C++内功修炼----面向对象的多态

0.概述 多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。实现多态,有二种方式,覆盖,重载。覆盖:是指子类重新定义父类的虚函数的做法。重载:是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数...

vjhghjghj的博客 501

Scott Meyers给出的他认为C++史上最强的五篇文章

下面是Scott Meyers给出的他认为C++史上最强的五篇文章,最早的也要到97年了,反正除了Template Metaprograms有点印象其它是都没看过,打算抽时间把这些大牛推荐的Non-Book Publications再消化一下。 Programming in C++, Rules and Recommendations by Mats Henricson and Erik Ny

freerock 2734

C++内功修炼----表达式

sizeof运算符 sizeof与strlen的区别 函 参 组 节 1)strlen计算字符串的具体长度(只能是字符串),不包括字符串结束符。返回的是字符个数。 2)sizeof计算声明后所占的内存数(字节大小),不是实际长度。 3)sizeof是一个取字节运算符,而strlen是个函数。 4)sizeof的返回值=字符个数*字符所占的字节数,字符实际长度小于定义的长度,此时字符个数就等于定...

vjhghjghj的博客 351

C++优秀文章

1、蓝乐:https://blog.youkuaiyun.com/love_guanghui/category_11380592.html 半生瓜のblog----《黑马程序员C++》课程笔记总结:https://blog.youkuaiyun.com/qq_51604330/article/details/119688133

weifeng blog 419

一文弄清using namespace std;的作用[2021最新版]

using namespace std;到底有什么用? 为什么我们每次头文件后面都要加它? 不加它会怎么样? 导读 对于很多学习C++的同学,老师教同学们写的一个程序就是“hello world”,同时也会在不经意间在头文件的后面加上using namespace std;但是却没有告诉我们为什么要这么加,所以很多同学可能现在仍然不明白他的作用。 本文将详细介绍using namespace std; 帮助大家彻底理解! using namespace std;概念命名空间的定义如何访问命名空间?为什.

CodeBowl的博客 5万+

一文带你彻底搞懂i++和++i的区别,谁的效率更高?

作者简介:Codebowl靓仔,学妹的工具人,C++开发误入数据开发,梦想30岁退休的靓仔就是我啦。 i++和++i对于初学者来说,一直是一个特别容易搞混的内容,相信很多人现在也没有完全搞清(作者初学的时候就一直稀里糊涂的,老师在讲这个的时候也一笔带过了)。 不过今天不用怕,看完这篇文章,相信你一定能搞清楚这俩个的区别! 一文带你彻底搞懂i++和++i的区别,谁的效率更高?基本概念++i和i++的区别i++和++i的原理单独使用时参与运算时i++和++i那个效率更高? 基本概念 两者的作用都是自增加1。.

CodeBowl的博客 4万+

最好用的json库,也许是JSON for modern C++ 的最佳实践!解决nlohmann json中文无法解析的问题!

GitHub开源项的地址:https://github.com/nlohmann/json json for modern c++是一个德国大牛nlohmann写的,该版本的json有以下特点: 1.直观的语法。 2.整个代码由一个头文件组成json.hpp,没有子项目,没有依赖关系,没有复杂的构建系统,使用起来非常方便。 3.使用c++11标准编写。 4.使用json 像使用STL容器一样。 5.STL和json容器之间可以相互转换。 如何使用? 只需要带一个文件即可。 #include <js.

CodeBowl的博客 5419

Windows环境下读取文件,输出中文乱码原因剖析及解决方案!

Windows读文件中文乱码问题描述问题复现直接输出中文读文件原因分析**3.文件编码格式**解决方案 问题描述 这俩天,遇到了一个问题,解析json的时候,中文老是乱码。 复现后,发现读取文件时,遇到中文,在控制台输出的时候也会乱码,遂进行详细分析和解决。 问题复现 直接输出中文 //直接输出中文 void test1() { std::cout << "中文测试!" << std::endl; } 直接控制台输出中文,没有毛病。 读文件 //读文件 void test2

CodeBowl的博客 3856
上一篇: 这次肯定可以看懂C++智能指针,适合新手小白,C++内功修炼
下一篇: C++最重要的知识点,学弟学妹现在搞起,进大厂必备!
CodeBowl
博客等级 码龄5年 7664粉丝 67原创
评论 11
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值