C++填坑系列——左值和右值

c++的表达式

首先介绍下c++的表达式是什么?看下cppreference是怎么说的。

An expression is a sequence of operators and their operands, that specifies a computation.

也就是说,在C++中,表达式(Expression)是由操作数(Operands)和运算符(Operators)组成的序列。

左值和右值就是c++中表达式的两种分类。

左值

简单理解,能够取地址的对象是左值,非临时对象的就是左值。

int a = 5;  // a就可以理解成是一个左值,5就可以理解为是一个右值
"hello world";  // 字符串常量值是个左值;字符串常量会申请内存空间,同样的字符串常量使用的是同一块内存;
Object &&obj = std::move();  // 右值引用本身也是个左值,他就是个变量其实,所以也有地址;

右值

c++11之前左值和右值的说法,c++11之后有了细分,又出现了纯右值和将亡值。c++11之前的右值就可以理解为c++11之后的纯右值,这里就直接说纯右值和将亡值了。

纯右值

  1. 纯粹的字面值,如 11false 等;
  2. 求值结果相当于字面值/一个临时对象。
  • 注1:字符串字面值是左值,它是可以进行取地址的操作;
std::cout << &("hello world") << std::endl;

输出的结果是0x100a2df44

  • 注2:++i 是左值,i++是右值

++i 和 i++类似于下面的代码,func1()返回的是一个临时对象;func2()返回的还是 i,用以区分左值还是右值。

// i++
int func1(int &i) {
  int tmp = i;
  i = i + 1;
  return tmp;
}
// ++i
int func2(int &i) {
  i = i + 1;
  return i;
}

将亡值

c++11 之前的右值和 c++11 的纯右值是等价的。

c++11 提出的将亡值是随右值引用引入的,将亡值和右值引用息息相关,将亡值可以按照字面意思来理解,就是快要“死亡”的值。

将亡值表达式:

  1. 返回右值引用的函数调用表达式;例如get_value()返回一个非引用类型的对象;
  2. 转换(cast)为右值引用的转换函数表达式。

何为“将亡”?

c++11 中,

  1. 用左值初始化一个对象/为一个已有对象赋值,会调用拷贝构造函数/拷贝赋值运算符,进行资源拷贝;
  2. 用右值来初始化/赋值时,会调用移动构造函数/移动赋值运算符来移动资源,避免资源拷贝。

当该右值完成初始化/赋值操作后,它的资源已经被移走了,同时该右值会马上被销毁,这就是“将亡”。

std::move()static_cast<X&&>()将左值转为右值,这里就涉及到了将亡值,转换为右值之后原值就被销毁掉了。

posted @ 2024-03-02 12:24  战斗天使zzy  阅读(105)  评论(0)    收藏  举报