【C++】右值引用(极详细版)(二)

简介: 在讲右值引用之前,我们要了解什么是右值?那提到右值,就会想到左值,那左值又是什么呢?我们接下来一起学习!

1.移动构造

我们用to_string()函数的返回值来构造ret对象,这就涉及到了函数传返回值时的拷贝问题

1.正常构造的过程:

但是编译器会自动优化(连续的构造,但是不是所有的情况都优化),将两个拷贝构造优化为一个拷贝构造,直接跳过中间的临时变量:

但是对于自定义类型时,虽然将两次拷贝构造优化为一次,拷贝构造仍然要消耗很大的空间,所以这时右值引用的第一个价值就要登场!


右值引用来补齐函数传返回值时的拷贝短板:


当调用拷贝构造时,之前我们只有传左值,进行深拷贝,完成拷贝构造;


但现在我们有了右值,可以传右值,那么传右值的拷贝构造是怎么搞的呢?


再举一个例子:


右值分为:纯右值(字面常量)和将亡值(更侧重于自定义类型的函数的返回值,表达式的返回值)。

当构造传左值,就走拷贝构造,当构造传右值,就走移动构造。


对于左值,我们后续还要使用,所以只能进行深拷贝,完成拷贝构造。


但对于右值(将亡值),可以直接进行资源的交换,将this和将亡值交换资源。


所以,回到函数传返回值的问题:

在 有了移动构造以后,再经过编译器的优化,就可以做到直接移动构造(资源的交换),实现0拷贝,效率极高!!

2.移动赋值

第一种情况是针对拷贝构造的情况,接下来是针对赋值拷贝的情况:

赋值拷贝同理可得:


目录
相关文章
|
6月前
|
算法 编译器 程序员
【C/C++ 解惑 】 std::move 将左值转换为右值的背后发生了什么?
【C/C++ 解惑 】 std::move 将左值转换为右值的背后发生了什么?
68 0
|
6月前
|
C++
c++左值和右值,左值引用和右值引用
c++左值和右值,左值引用和右值引用
54 0
|
2月前
|
编译器 C++
C++ 11新特性之右值引用
C++ 11新特性之右值引用
43 1
|
6月前
|
编译器 C语言 C++
从C语言到C++_33(C++11_上)initializer_list+右值引用+完美转发+移动构造/赋值(中)
从C语言到C++_33(C++11_上)initializer_list+右值引用+完美转发+移动构造/赋值
35 1
从C语言到C++_33(C++11_上)initializer_list+右值引用+完美转发+移动构造/赋值(中)
|
6月前
|
存储 安全 C语言
从C语言到C++_33(C++11_上)initializer_list+右值引用+完美转发+移动构造/赋值(上)
从C语言到C++_33(C++11_上)initializer_list+右值引用+完美转发+移动构造/赋值
33 2
|
6月前
|
编译器 C语言 C++
从C语言到C++_33(C++11_上)initializer_list+右值引用+完美转发+移动构造/赋值(下)
从C语言到C++_33(C++11_上)initializer_list+右值引用+完美转发+移动构造/赋值
36 1
|
5月前
|
编译器 C++ 开发者
C++一分钟之-右值引用与完美转发
【6月更文挑战第25天】C++11引入的右值引用和完美转发增强了资源管理和模板灵活性。右值引用(`&&`)用于绑定临时对象,支持移动语义,减少拷贝。移动构造和赋值允许有效“窃取”资源。完美转发通过`std::forward`保持参数原样传递,适用于通用模板。常见问题包括误解右值引用只能绑定临时对象,误用`std::forward`,忽视`noexcept`和过度使用`std::move`。高效技巧涉及利用右值引用优化容器操作,使用完美转发构造函数和创建通用工厂函数。掌握这些特性能提升代码效率和泛型编程能力。
47 0
|
6月前
|
编译器 C++ 容器
【C++11(一)】右值引用以及列表初始化
【C++11(一)】右值引用以及列表初始化
|
6月前
|
存储 安全 程序员
C++11:右值引用
C++11:右值引用
45 0
|
6月前
|
存储 算法 程序员
【C++入门到精通】右值引用 | 完美转发 C++11 [ C++入门 ]
【C++入门到精通】右值引用 | 完美转发 C++11 [ C++入门 ]
54 0