C++指针,左值引用,右值引用详解 - 弦外之音 (xianwaizhiyin.net)
1
现在,我们得出结论,右值引用 的底层逻辑,就是一级指针。
扩展知识:《C++ Primer》提到 右值是临时现象,实际上指的就是那个 nobody 匿名变量,没有名称的变量。
我们再来看右值引用的一个复杂的例子,C++ 提供了 std::move()
,我们用这个 move
函数来演示,代码如下:
#include <iostream>
class Box
{
public:
int length; // 盒子的长度
int breadth; // 盒子的宽度
int height; // 盒子的高度
};
int main()
{
Box b1;
b1.length = 10;
b1.breadth = 20;
b1.height = 30;
Box b2 = b1;
b1.length = 55;
printf("b2.length = %d \n", b2.length);
}
上面的代码运行如下:
可以看到,b2 并没有受到 b1 赋值的影响,所以 b2.length
等于 10,而不是 55。因此 b1 变量 跟 b2 变量实际上是两块不同的内存。这叫做拷贝赋值
2
下面我们用 std::move()
来赋值 b2 ,如下:
#include <iostream>
class Box
{
public:
int length; // 盒子的长度
int breadth; // 盒子的宽度
int height; // 盒子的高度
};
int main()
{
Box b1;
b1.length = 10;
b1.breadth = 20;
b1.height = 30;
Box&& b2 = std::move(b1);
b1.length = 55;
printf("b2.length = %d \n", b2.length);
}
运行如下:
[图片上传失败...(image-ec3cba-1686292405652)]
可以看到 b2 受到了 b1 赋值的影响,所以他们已经指向同一块内存数据。
实际上上面的代码等价与 一级指针的写法,如下:
所以右值引用 ,move 函数的本质是什么呢?实际上就是取地址,复制地址,减少拷贝。
我个人的理解是这样的,虽然 C++ 是兼容 C 语言的,所以你可以用 一级指针,二级指针,但是 C++ 委员会貌似一直想在 C++ 里面去掉 指针的用法,所以他们发明了 右值引用 跟 move,实际就是为了 区分 拷贝 跟 移动 这两个操作。移动实际上就是取地址,然后把地址放到另一个变量。
所以可以把 右值引用 看成 是指针的替代品。但我个人认为,指针比右值引用容易使用很多。