左值引用和右值引用
#CPP
2024-11-09
左值和右值的区分
左值是取地址,代表持续存活之物
右值不可以取地址,代表即将消亡之物
示例见下:num 是左值,3 是右值。
1 |
|
左值引用和右值引用
无论左值引用还是右值引用,本质都是引用,即都是给对象取别名。
传统的 C++ 语法中就存在引用语法,而 C++11 标准中新增了右值引用的语法特性,因此为了区分两者,将 C++11 标准出现之前的引用称为左值引用。
左值引用就是对左值的引用,给左值取别名。主要作用是避免对象拷贝。
1 |
|
右值引用就是对右值的引用,给右值取别名。主要作用是延长对象的生命周期,一般是延长到作用域之外。广泛用于实现移动语义和完美转发。
1 |
|
代码示例:
1 |
|
转换
此前我们说左值引用绑定左值,右值引用绑定右值。
那么,左值引用可以绑定右值吗?右值引用可以绑定左值吗?
右值到左值引用的绑定
右值可以通过const 左值引用进行绑定,虽然右值通常没有持久的地址,但 C++ 允许我们使用 const
左值引用来绑定一个右值。这种绑定可以使临时对象的生命周期延长至引用的作用域结束。
1 |
|
这里,右值 10
可以通过 const int&
绑定到 ref
,从而延长了 10
的生命周期。在这种情况下,ref
只能被读取,不能被修改。
左值到右值引用的转换
左值可以通过 std::move
显式地转换成右值引用,这使得一个本来是左值的对象可以被移动语义所使用。例如在移动构造函数和移动赋值运算符中,使用 std::move
将左值转为右值引用以实现高效的资源转移。
1 |
|
这里 std::move(a)
将左值 a
转为右值引用,因此可以传递给 process
函数。需要注意,使用 std::move
后,a
的状态可能变成“未定义”,通常在此之后不应再直接使用 a
,除非它被重新赋值。
为什么出现右值引用和移动语义?
因为有个问题,左值引用解决不了,见下:
1 |
|