C++中的左值和右值

左值和右值

概述:

  • 左值:指向一个指定内存的,具有名称的值,它通常拥有一个稳定的内存地址,并且有一段较长时间的生命周期。
  • 右值:通常不指向稳定内存地址的匿名值,生命周期很短,通常是暂时的。
  • 基于此特性,可以取地址符来判断,能取到地址的是左值,不能取到地址的是右值

前置++和后置++

  • 前置++:实现是直接对传入的对象自增,然后将此对象返回,因此它返回的是一个具有名称的稳定的值,它是一个左值
  • 后置++:实现是创建一个临时对象,然后对传入的对象自增,但是返回的是这个临时对象

左值引用: 普通的引用类型,它绑定到左值。

定义:

1
2
int a = 10;
int&ref = a; // ref是a的左值引用

场景:在函数参数传递时,通常用于避免不必要的复制,节省性能

右值引用: 是C++11引入的新特性,它绑定到右值

定义:

1
int&& ref = 10; // 10 是一个右值

场景:通过启用移动语义,可以显著优化性能,特别是在处理临时对象和大对象时。一个重要应用是转移资源(如动态内存、文件句柄等),而不是进行昂贵的复制

移动语义:通过右值引用和std::move,可以将一个对象的资源转移到另一个对象,而不是复制一份相同的资源(类似于rust中的move关键字)

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <vector>
void process_vector(std::vector<int>& v) {
// 通过左值引用,复制传入的 v
std::cout << "Left value reference\n";
}
void process_vector(std::vector<int>&& v) {
// 通过右值引用,移动传入的 v
std::cout << "Right value reference\n";
}
int main() {
std::vector<int> vec1 = {1, 2, 3};
process_vector(vec1); // 左值引用调用

process_vector(std::vector<int>{1, 2, 3}); // 右值引用调用
}

RVO(Return Value Optimization):

是一种编译器优化技术,用于消除不必要的临时对象拷贝,从而提高代码性能。主要针对函数返回局部对象的情况,通过优化,可以避免创建临时对象并执行拷贝构造函数。

RVO基本思想:在函数调用栈上直接构造返回值,而不是先构造一个局部对象,然后再拷贝到调用者的栈空间。这样可以减少临时对象的创建和销毁,提高代码运行效率。

移动构造函数:

就是构造函数使用右值引用作为接收,可以使我们在构造新对象时,将资源聪一个右值“move”到新对象,而不是创建新资源的拷贝,可以避免不必要的拷贝操作,从而提高代码的性能

存在的问题:当一个对象的资源移动到另一个对象时发生了异常,这样就会导致新对象是不完整的。可以使用noexcept说明符限制该移动构造函数,这样函数抛出异常时就会停止以免造成其他影响


C++中的左值和右值
http://example.com/2024/12/20/C-中的左值和右值/
作者
凌云行者
发布于
2024年12月20日
许可协议