C++11之一场名为“搬家”的 C++ 之旅

一、左值VS右值

在C++中,每一个变量或者表达式,都有一个身份:要么是左值,要么是右值

  • 左值:有名字、有固定住址的永久居民

比如:int a = 10;这里的a就是左值。你看可以通过&a找到它的家庭住址

  • 右值:没名字、四处漂泊的临时过客

比如10,a + 5,或者一个函数返回的临时对象。它们马上就要消息了,你没法用&取它们的地址

cpp 复制代码
#include <iostream>
using namespace std;

int main() {
    int a = 10; // a 是左值,10 是右值
    
    cout << "a 的地址: " << &a << endl; // ✅ 合法,a 有地址
    // cout << &10 << endl;            // ❌ 非法,10 没有地址(右值)
    // cout << &(a+5) << endl;         // ❌ 非法,a+5 的结果没有地址(右值)
    
    return 0;
}

二、引用是什么?

引用就是给变量取个"外号",操作外号就等于操作变量本身

1、左值引用(&):只能给持久居民起外号

bash 复制代码
int a = 10;
int& ref1 = a;      // ✅ 合法,ref1 是 a 的外号
// int& ref2 = 10;  // ❌ 非法,不能给临时过客起外号(没住址)

2、常引用(const &):老好人谁都能绑

cpp 复制代码
int a = 10;
const int& ref3 = a;  // ✅ 合法
const int& ref4 = 10; // ✅ 合法!虽然是临时过客,但老好人给它续命了(延长了生命周期)
// ref4 = 20;         // ❌ 非法,因为是 const(只读外号)

3、右值引用(&&):专为临时过客准备的外号

cpp 复制代码
int a = 10;
// int&& ref5 = a;    // ❌ 非法,右值引用不能绑持久居民(左值)
int&& ref6 = 10;      // ✅ 合法,绑定临时过客(右值)
int&& ref7 = a + 5;   // ✅ 合法,绑定临时过客(右值)

注意:右值引用变量自己,是个左值!

这一点极其重要!C++ 规定:只要一个变量有名字,它就是左值 。所以 ref6 虽然类型是右值引用,但它自己有名字,它就是个左值

cpp 复制代码
int&& ref8 = 10;
// int&& ref9 = ref8;  // ❌ 非法!因为 ref8 有名字,被当作左值!
int&& ref9 = std::move(ref8); // ✅ 必须用 std::move 把它重新变成右值

三、为什么要有右值引用?

假设你要写一个 String 类,里面有一个指针 char* ptr;。

  • 当你把一个左值赋给另一个左值 时,你不能偷别人的数据(别人还要用),所以你只能深拷贝 (重新申请一块内存,把字串复制过去)。这叫拷贝赋值。

  • 但是,当你把一个右值(临时对象)赋给另一个左值 时,反正临时对象马上要死了,我们为什么不直接把它的指针"偷"过来 呢?这就叫移动赋值!

四、std::move是什么?

真相:std::move 根本没有移动任何东西!

它就像一个"魔法标签"。你把一个左值传进去,它就给你贴个标签:"虽然它是个左值,但我宣布,从现在起,你就把它当成右值用!"

它的底层实现其实是强制类型转换:

cpp 复制代码
// 你写:
std::move(a);
// 编译器实际干的事:
static_cast<int&&>(a); // 强行把 a 转成右值引用类型

被 std::move 标记过的左值,它的资源就可以被安全地"偷走"了。所以 std::move 最好只用在"你确定以后不再使用这个变量"的时候

相关推荐
紧跟先前的步伐1 分钟前
Go AI Agent 实战 17|模型适配层设计:让模型可替换
开发语言·人工智能·后端·ai·golang
小灰灰搞电子12 分钟前
Qt 中使用 QSettings 存储结构体数据详解
开发语言·qt
外收内放17 分钟前
FastAPI猜字谜实战(5):会话管理
开发语言·python·学习·fastapi
Ai-_Man18 分钟前
Microsoft Copilot对话数据怎么导入到另外一个Microsoft Copilot账号里去?AI导出鸭
开发语言·javascript·人工智能·microsoft·chatgpt·ecmascript·copilot
H.莓飛23 分钟前
【数据结构】归并与外排序
linux·服务器·c语言·开发语言·数据结构·visual studio
技术老孙25 分钟前
给 Agent 装上对话框 —— AgentScope-Java 接入 Spring Boot 与 SSE 流式实战
java·开发语言·spring boot
Yyyyyy~1 小时前
【C++】String
c++
星夜离尘569 小时前
MATLAB 工程实验:不等间隔流量积分,先把缺口与覆盖率说清楚
开发语言·matlab·时间戳·数据质量·数值积分
Ai-_Man9 小时前
Meta Muse还是不可以导出左侧所有对话,只能点进去单条内容导出,方法不对吗?
开发语言·人工智能·ai·小程序·c#·1024程序员节
梓豪csd9 小时前
消息订阅中心:谁该收到哪条通知
java·开发语言·人工智能·低代码·自动化·1024程序员节