C++ 左值(lvalue)和右值(rvalue)

在 C++ 中,左值(lvalue)和右值(rvalue)是指对象的不同类别,区分它们对于理解 C++ 中的表达式求值和资源管理非常重要,尤其在现代 C++ 中涉及到移动语义(Move Semantics)和完美转发(Perfect Forwarding)时。

一、左值(Lvalue)

1. 定义

左值(lvalue)表示的是一个有名称的、持久的内存位置,可以在表达式的左侧,也可以在右侧使用。简单来说,左值是可以通过引用来访问的对象,它在程序的生命周期中有一个持久的存储位置。

2. 特征

  • 可修改:大多数左值是可修改的(当然,常量左值不可修改)。
  • 有持久地址:左值有内存地址,可以通过 & 取地址。

3. 例子

int x = 10;   // x 是一个左值,代表存储它的内存位置
x = 20;       // x 作为左值出现在赋值表达式的左侧

4. 常见的左值类型

  • 普通变量:如 int x = 10; 中的 x
  • 数组元素:如 arr[3]
  • 对象成员:如 obj.member
  • 解引用指针:如 ptr

二、右值(Rvalue)

1. 定义

  • 右值(rvalue)表示的是临时对象或不具有持久内存位置的对象,通常是表达式的结果。右值可以出现在赋值表达式的右侧,但不能出现在左侧(除非作为右值引用)。

2. 特征

  • 无持久地址:右值通常是一个临时对象,它在某些情况下会被销毁。
  • 不能修改:右值本身不表示一个持久的存储位置,所以不能被赋值或取地址。

3. 例子

int x = 10;  // x 是左值
int y = 20;  // y 是左值
y = x + 5;   // (x + 5) 是右值,表示一个临时结果

4. 常见的右值类型

  • 字面量:如 53.14'a' 等。
  • 临时对象:如表达式的返回值,例如 x + y 返回一个临时结果。
  • 函数返回值:如返回一个非引用的临时值 int foo() { return 42; }
  • 类型转换:如 (int)3.14 或 std::move(x)

三、右值引用(Rvalue Reference)

C++11 引入了右值引用(T&&),使得我们能够有效地使用右值(临时对象)进行资源转移(例如移动语义)。右值引用允许对象的资源不需要复制,而是可以直接“移动”到新的对象中,这样能提高程序的效率,避免不必要的资源复制。

1. 右值引用的使用

  • 右值引用的声明通常为 T&&(例如,int&&)。
  • std::move 将一个左值转换为右值引用,从而启用移动语义。
  • 移动构造函数和移动赋值运算符通常采用右值引用作为参数,允许从临时对象中“偷取”资源。

2. 示例

#include <iostream>#include <vector>void printVector(std::vector<int>&& v) {for (auto i : v) {std::cout << i << " ";}std::cout << std::endl;
}int main() {printVector({1, 2, 3, 4, 5});  // 使用右值传递临时对象return 0;
}

在这个例子中,{1, 2, 3, 4, 5} 是一个右值,可以作为右值引用参数传递给 printVector 函数。

四、区别与联系

  • 左值(Lvalue):表示一个持久的对象,它有地址并且可以被修改。例如,变量、数组元素、解引用指针等。
  • 右值(Rvalue):表示一个临时对象或没有持久地址的值,通常出现在赋值语句的右边。它们通常不可修改。
  • 右值引用(Rvalue Reference):C++11 引入的一种新类型,允许我们将右值传递给函数,从而避免资源的复制(通过移动语义)。右值引用通过 T&& 来表示。

五、C++11 中的扩展:完美转发和移动语义

1. 完美转发(Perfect Forwarding)

通过右值引用,我们可以将函数的参数完美地转发到另一个函数,无论是左值还是右值。使用 std::forward 可以实现完美转发。

template<typename T>
void wrapper(T&& arg) {func(std::forward<T>(arg));  // 完美转发 arg 到 func 函数
}

2. 移动语义(Move Semantics)

右值引用可以用于“移动”资源,而不是复制它们。移动构造函数和移动赋值运算符允许通过“转移”资源来避免不必要的内存复制。

std::vector<int> getVector() {std::vector<int> v = {1, 2, 3, 4};return v;  // 返回一个右值
}int main() {std::vector<int> v = getVector();  // 通过移动语义,避免了不必要的复制
}

六、总结

  • 左值(Lvalue):有持久存储位置,通常表示变量或对象。
  • 右值(Rvalue):没有持久存储位置,通常表示临时对象或值。
  • 右值引用(Rvalue Reference):用于支持移动语义,允许我们移动而不是复制资源。

通过区分左值和右值,C++ 提供了更高效的内存管理方式,尤其在现代 C++ 中,移动语义和完美转发能够显著提高性能。

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

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

相关文章

【含文档+PPT+源码】基于SpringBoot和Vue的编程学习系统

项目介绍 本课程演示的是一款 基于SpringBoot和Vue的编程学习系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系统 3.该项…

关于新奇的css

background: linear-gradient(154deg, #07070915 30%, hsl(var(--primary) / 30%) 48%, #07070915 64%); filter: blur(100px); background: linear-gradient(154deg, #07070915 30%, hsl(var(--primary) / 30%) 48%, #07070915 64%); 这是一个线性渐变背景设置&#xff0c;角度…

Maxscript如何通过单击现有按钮添加新按钮?

创建一个按钮,你可以单击它,然后添加一个新按钮。 你必须创建一个动态UI,使用maxscript UI元素,将卷展栏构建为字符串,然后评估该字符串并打开新的卷展栏以更新你的UI;使用RolloutCreator(请参阅帮助文件)帮助您构建卷展栏,并打开新的卷展栏以更新您的UI,看下面的示…

Android控件Selector封装优化指南:高效实现动态UI效果

本文详细介绍了如何在Android开发中优化selector的封装&#xff0c;涵盖Button、TextView、ImageView、CheckBox、RadioButton等常见控件的动态效果实现。通过结合Material Design组件、矢量图、Ripple效果以及动画Selector&#xff0c;提供了一套现代化、高性能的解决方案&…

pytest+allure+jenkins

本地运行参考&#xff1a;pytestallure 入门-CSDN博客 jenkins运行如下&#xff1a; 安装插件&#xff1a;allure 配置allure安装目录 配置pytest、allure 环境变量 配置流水线 进行build,结果如下 ,点击allure report 查看结果

C#核心笔记——(五)框架概述

.NET Ftamework中几乎所有功能都是通过大量的托管类型提供的。这些类型组织在层次化的命名空间中&#xff0c;并打包为一套程序集&#xff0c;与CLR一起构成了.NET平台。 有些.NET类型是由CLR直接使用的&#xff0c;且对于托管宿主环境而言是必不可少的。这些类型位于一个名为…

phpstudy+phpstorm+xdebug【学习笔记】

配置PHPStudy 配置PHPSTORM phpstorm选择PHP版本 配置DEBUG 设置服务器 编辑配置 学习参考链接&#xff1a;&#xff1a;https://blog.csdn.net/m0_60571842/article/details/133246064

Vue:Vue+TS学习笔记

文章目录 前文Vue 3学习 Vue3 的重要性变更内容 底层逻辑选项式 API 和组合式 API体验组合式 API很多钩子组件通信 和 TS 结合开发为什么要用 TS? 正式上手 Vuets 开发给 ref 添加类型标记。ref, reactive, computed 综合代码模板引用类型传值写法 解决问题: 第三方包想要有类…

ACwing—01背包(暴力bfs+dp+递归+记忆化搜索算法)

问题 有 N件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi&#xff0c;价值是 wi。 求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;且总价值最大。 输出最大价值。 输入格式 第一行两个整数&#xff0c…

洛谷 P2801 教主的魔法 题解

之前学过 莫队 算法&#xff0c;其运用了分块思想&#xff1b;但是我居然是第一次写纯种的分块题目。 题意 给你一个长度为 n n n 的序列 a a a&#xff08;一开始 ∀ a i ∈ [ 1 , 1000 ] \forall a_i\in[1,1000] ∀ai​∈[1,1000]&#xff09;。要求执行 q q q 次操作&…

leetcode 75.颜色分类(荷兰国旗问题)

题目描述 题目分析 本题是经典的「荷兰国旗问题」&#xff0c;由计算机科学家 Edsger W. Dijkstra 首先提出。 要想单独解决这道题本身还是很简单的&#xff0c;统计0、1、2的数量然后按顺序赋值&#xff0c;或者手写一个冒泡排序&#xff0c;whatever。 但是在这一题中我们主…

rc4算法简单介绍及实现

0. 介绍 RC4是一种流密码&#xff0c;但因为安全性问题已经被弃用。 1. 算法描述 1.1 初始化 Key为生成的随机密钥&#xff1a;1-256B S为一数组&#xff1a;256B T为辅助数组&#xff1a;keylenB for (int i 0;i < 256;i) {S[i] i;T[i] S[i % keylen]; }1.2 初始化…

OpenEuler20.3 安装 Elasticsearch7.17

1、下载elasticsearch wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.17-linux-x86_64.tar.gz wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.17-linux-x86_64.tar.gz.sha512 shasum -a 512 -c elasticsea…

单元测试知识总结

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、什么是单元测试&#xff1f; 单元测试是指&#xff0c;对软件中的最小可测试单元在与程序其他部分相隔离的情况下进行检查和验证的工作&#xff0c;这里的…

python爬虫笔记(一)

文章目录 html基础标签和下划线无序列表和有序列表表格加边框 html的属性a标签&#xff08;网站&#xff09;target属性换行线和水平分割线 图片设置宽高width&#xff0c;height html区块——块元素与行内元素块元素与行内元素块元素举例行内元素举例 表单from标签type属性pla…

【mysql】centOS7安装mysql详细操作步骤!—通过tar包方式

【mysql】centOS7安装mysql详细操作步骤&#xff01; linux系统安装mysql版本 需要 root 权限&#xff0c;使用 root 用户进行命令操作。使用tar文件包&#xff0c;安装&#xff0c;gz包也可以但是还需要配置用户&#xff0c;tar包虽然大&#xff0c;但是全啊&#xff01; 1. …

[新能源]新能源汽车快充与慢充说明

接口示意图 慢充接口为交流充电口&#xff08;七孔&#xff09;&#xff0c;快充接口为直流充电口&#xff08;九孔&#xff09;。 引脚说明 上图给的是充电口的引脚图&#xff0c;充电枪的为镜像的。 慢充接口引脚说明 快充接口引脚说明 充电流程 慢充示意图 慢充&…

Android第二次面试总结(项目拷打理论篇)

&#xff08;一&#xff09;理论基础 LiveData 和 ViewModel 是 Android 架构组件中的重要部分&#xff0c;它们在构建响应式、生命周期感知的 Android 应用程序中发挥着关键作用。下面分别介绍它们的原理。 LiveData 原理 1. 概述 LiveData 是一种可观察的数据持有者类&…

MyBatis SqlSessionFactory 是如何创建的?

SqlSessionFactory 是 MyBatis 的核心接口之一&#xff0c;它是创建 SqlSession 实例的工厂。 SqlSession 实例是 MyBatis 与数据库交互的主要接口&#xff0c;负责执行 SQL 语句、管理事务等。 SqlSessionFactory 的创建过程主要由 SqlSessionFactoryBuilder 类负责。 SqlSes…

玩转python:通俗易懂掌握高级数据结构-collections模块之Counter

引言 Counter是Python中collections模块提供的一个强大工具&#xff0c;用于统计可哈希对象的出现次数。它非常适合用于频率统计、词频分析、数据聚合等场景。本文将详细介绍Counter的关键用法和特性&#xff0c;并通过8个丰富的案例帮助读者掌握其应用。 关键用法和特性表格 …