c++基础·左值右值

一、左值与右值的本质特征

1. 基础定义

  • 左值 (lvalue)
    ✅ 可出现在赋值运算符左侧
    ✅ 可被取地址(有明确存储位置)
    ✅ 通常为具名变量(如int a = 10;中的a

  • 右值 (rvalue)
    ❌ 不可出现在赋值左侧
    ❌ 不可取地址(无持久存储位置)
    ✅ 通常是临时对象或字面量(如5a+1

2. 双维度鉴别法

法一:赋值能力测试

int x = 10;    // x是左值  
x = 20;        // 合法  
// 10 = x;     // 错误:右值不可被赋值  

法二:地址操作验证

int* p1 = &x;  // 成功  
// int* p2 = &(x+1); // 失败:表达式结果无地址  

二、引用类型深度解析

1. 左值引用

规则:只能绑定左值

int a = 10;  
int& ref1 = a;     // ✅ 正确  
ref1 = 20;         // 修改原值  // int& ref2 = 5;  // ❌ 错误:无法绑定右值  
const int& cref = 5; // ✅ 特殊允许(编译器创建临时对象)  

2. 右值引用(完整保留你的代码逻辑)

规则:绑定右值或通过std::move转换

int&& rref1 = 10;            // ✅ 直接绑定字面量  
int b = 20;  
// int&& rref2 = b;         // ❌ 错误:b是左值  
int&& rref3 = std::move(b);  // ✅ 强制转换(原对象进入"将亡"状态)  

代码陷阱示例

std::string s1 = "Hello";  
std::string&& s2 = std::move(s1);  
std::cout << s1; // 输出结果不确定!可能为空或保留原值  

三、左值/右值引用应用场景

1. 左值引用典型用途

参数传递(避免拷贝)

void processBigData(const std::vector<int>& data) {  // 避免拷贝大型对象  
}  

操作容器元素

std::vector<int> vec{1,2,3};  
int& elem = vec[0]; // 直接修改元素  

2. 右值引用核心价值

实现移动语义(资源转移)

class String {  char* data;  
public:  // 移动构造函数  String(String&& other) noexcept   : data(other.data)  {  other.data  = nullptr; // 原对象放弃资源  }  
};  

完美转发(保留参数特性)

template<typename T>  
void relay(T&& arg) {  target(std::forward<T>(arg));  
}  

四、纯右值详解(完整保留你的分类)

1. 纯右值 (prvalue) 类型

类别示例
字面量(除字符串外)423.14'a'
算术/逻辑表达式结果a + bx && y
返回非引用的函数调用std::string("temp")
Lambda表达式[](){ return 5; }()

2. 典型场景代码

int getValue() { return 100; }  int main() {  int c = getValue(); // 函数返回值是纯右值  int d = c++;        // c++是纯右值(返回旧值副本)  
}  

五、关键知识扩展

1. 移动语义性能对比

传统拷贝 vs 移动操作

// 拷贝语义(高开销)  
std::vector<int> v1(1000000, 5);  
std::vector<int> v2 = v1; // 深拷贝  // 移动语义(零拷贝)  
std::vector<int> v3 = std::move(v1); // 仅指针交换  

2. std::move本质解析

  • 不做任何资源移动
  • 仅执行左值到右值的静态类型转换
  • 实际移动操作由对象的移动构造函数/赋值运算符实现

六、常见误区与解答

❓ 问题1:右值引用变量本身是左值还是右值?
✅ 解答:右值引用变量是左值!它有名字且可被取地址:

int&& rref = 10;  
int* p = &rref;  // 合法操作  

❓ 问题2const左值引用为何能绑定右值?
✅ 解答:编译器隐式创建临时对象并绑定,生命周期延长至引用结束

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

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

相关文章

【Rust 精进之路之第9篇-所有权·核心】规则与移动 (Move):Rust 内存安全基石详解

系列: Rust 精进之路:构建可靠、高效软件的底层逻辑 作者: 码觉客 发布日期: 2025年4月20日 引言:没有 GC,Rust 如何管好内存?答案是所有权! 在我们的 Rust 探索之旅中,我们已经学习了变量、数据类型、控制流、函数和强大的构建工具 Cargo。现在,我们将踏入 Rust 最…

嵌入式学习——opencv图像库编程

环境配置 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉和图像处理库&#xff0c;广泛用于各种计算机视觉任务&#xff0c;如图像处理、视频分析、人脸识别、物体检测、机器学习等。它提供了丰富的函数和工具&#xff0c;用于处理…

一招破敌,掌控 React 渲染术:createRoot 与 root.render

前言 在这数字江湖中,前端门派百花齐放,React 一门尤为奇特,讲究“以虚制实,以组件驭天下”。眼下你我初入江湖,第一关便是挂载组件之术。倘若不懂 createRoot 与 root.render,那就像一个新晋小侠,连起手式都没学会,点穴还没碰到 DOM,自己先内伤三分。 来吧,少年!…

Linux常见工具如yum、vim、gcc、gdb的基本使用,以及编译过程和动静态链接的区别

目录 一、工具的本质 二、一些常用的工具 1.yum 2.vim 1&#xff09;vim的三种基本模式&#xff1a; 2&#xff09;vim的基本操作 ①命令模式下的基本操作&#xff1a; ②插入模式&#xff1a; ③底行模式&#xff1a; 3&#xff09;vim的配置&#xff1a;让他变得更好用 3.gcc…

JavaScript 一维数组转不含零的两个数

问题描述&#xff1a; /*** param {number} n* return {number[]}*/ var getNoZeroIntegers function(n) {for(let i 1;i<n;i){if(String(i).indexOf(0) -1&&String(n-i).indexOf(0) -1){return [i,n-i]}}};String类型indexOf()函数如果找不到字串则返回-1&…

力扣DAY60-61 | 热100 | 回溯:单词搜索、分割回文串

前言 中等 √ 继续回溯&#xff0c;不知咋地感觉这两题有点难度&#xff0c;是因为隔一天就手感生疏了吗&#xff1f; 单词搜索 我的题解 定义方向数组、二维访问数组。图搜索&#xff0c;向上下左右每个方向搜索&#xff0c;需要更新的信息&#xff1a;坐标、是否遍历过、…

超简单的git学习教程

本博客仅用于记录学习和使用 前提声明全部内容全部来自下面廖雪峰网站&#xff0c;如果侵权联系我删除 0.前言 相信有不少人被推荐那个游戏学习git&#xff0c;一个不止我一个完全没学习过的进去后一脸懵&#xff0c;半天都通不过一关然后就放弃了&#xff0c;我个人觉得那个…

【每日八股】复习 MySQL Day1:事务

文章目录 复习 MySQL Day1&#xff1a;事务MySQL 事务的四大特性&#xff1f;并发事务会出现什么问题&#xff1f;MySQL 事务的隔离级别&#xff1f;不同事务隔离级别下会发生什么问题&#xff1f;MVCC 的实现原理&#xff1f;核心数据结构版本链构建示例可见性判断算法MVCC 可…

在极狐GitLab 身份验证中如何使用 OIDC?

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 使用 OpenID Connect 作为认证提供者 (BASIC SELF) 您可以使用极狐GitLab 作为客户端应用程序&#xff0c;与 OpenID Connec…

PHP腾讯云人脸核身生成 SDK 接口调用步骤使用签名

参考腾讯云官方文档&#xff1a; 人脸核身 生成 SDK 接口调用步骤使用签名_腾讯云 前提条件&#xff1a;成功获取NonceTicket。 获取参考文档&#xff1a; PHP腾讯云人脸核身获取NONCE ticket-CSDN博客 function getTxFaceSign(){$appId ;$userId ;$version 1.0.0;$tic…

每日一题算法——链表相交

链表相交 力扣题目链接 暴力解法:飘过 class Solution { public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {ListNode * cur headA;while(cur ! NULL){ListNode* curb headB;while(curb ! NULL){if(curbcur){return cur;}curb curb->next;}cu…

详解Windows(一)——系统盘下目录及文件详解

引言 你是否曾经好奇过电脑里那些神秘的文件夹都是干什么用的&#xff1f;为什么有些文件是.exe而有些是.dll&#xff1f;不同的图片格式.jpg和.png到底有什么区别&#xff1f;如果你对这些问题感到困惑&#xff0c;这篇文章就是为你准备的。今天&#xff0c;我们将以通俗易懂…

大模型赋能工业制造革新:10个显效可落地的应用场景

在工业4.0的汹涌浪潮中&#xff0c;制造业正面临着前所未有的转型挑战。传统制造模式在效率、成本、质量等方面逐渐难以满足市场需求&#xff0c;企业急需借助新技术实现数字化转型&#xff0c;以提升自身竞争力。在此背景下&#xff0c;基于先进的数据分析技术、大模型、知识图…

AI语音助手 React 组件使用js-audio-recorder实现,将获取到的语音转成base64发送给后端,后端接口返回文本内容

页面效果&#xff1a; js代码&#xff1a; import React, { useState, useRef, useEffect } from react; import { Layout, List, Input, Button, Avatar, Space, Typography, message } from antd; import { SendOutlined, UserOutlined, RobotOutlined, AudioOutlined, Stop…

pycharm无法识别到本地python的conda环境解决方法

问题一 现象描述&#xff1a; 本地已经安装了conda&#xff0c;但在pycharm中选择conda环境却识别不到&#xff0c; 解决方法&#xff1a;手动输入conda path&#xff0c;点击R eload environments基本就能修复&#xff0c;比如我的路径如下 /Users/test/conda/miniconda3/b…

PDK中technology file从tf格式转换为lef格式

在数字后端流程中需要导入technology file工艺文件&#xff0c;一般传统的PDK中都提供.tf形式&#xff0c;能够在Synopsys ICC中进行导入。但是由于Cadence Innovus不断地完善&#xff0c;更多的工程采用了其进行数字后端设计。不过Cadence Innovus导入的是.lef格式的工艺文件&…

UE虚幻4虚幻5动画蓝图调试,触发FellOutOfWorld事件和打印输出,继续DeepSeek输出

找到了一个pdf&#xff0c;本来想写个翻译的&#xff0c;但还是算了&#xff0c;大概看了下&#xff0c;这类文档很全面&#xff0c;内容很多&#xff0c;但都不是我要的&#xff0c;我想要一个动画蓝图&#xff0c;搜索Montage&#xff0c;或者Anim 只占了一行&#xff08;几百…

【Sa-Token】学习笔记05 - 踢人下线源码解析

目录 前言 强制注销 踢人下线 源码解析 前言 所谓踢人下线&#xff0c;核心操作就是找到指定 loginId 对应的 Token&#xff0c;并设置其失效。 上图为踢人下线后&#xff0c;前端应该用图像给出来让用户重新登录&#xff0c;而不是让前端收到一个描述着被下线 的JSON 强…

C语言==》字符串断行

示例代码 #include <stdio.h>int main(void) {printf("Heres one way to print a ");printf("long string.\n");printf("Heres another way to print a \ long string.\n");printf("Heres the newest way to print a ""lo…

Linux | I.MX6ULL 文件系统

01 本节所有的测试程序需要开发板有 Qt 环境来运行。我们提供的文件系统是由 yocto 裁剪整理得来的。之后我们会整理一份单独移植的 qt 系统。方便用户移植第三方软件。如果用户的文件系统非我们的出厂版本,请参考之前烧写章节重新烧写出厂文件系统。开发板启动需要输入登录…