1.移动构造
我们用to_string()函数的返回值来构造ret对象,这就涉及到了函数传返回值时的拷贝问题:
1.正常构造的过程:
但是编译器会自动优化(连续的构造,但是不是所有的情况都优化),将两个拷贝构造优化为一个拷贝构造,直接跳过中间的临时变量:
但是对于自定义类型时,虽然将两次拷贝构造优化为一次,拷贝构造仍然要消耗很大的空间,所以这时右值引用的第一个价值就要登场!
右值引用来补齐函数传返回值时的拷贝短板:
当调用拷贝构造时,之前我们只有传左值,进行深拷贝,完成拷贝构造;
但现在我们有了右值,可以传右值,那么传右值的拷贝构造是怎么搞的呢?
再举一个例子:
右值分为:纯右值(字面常量)和将亡值(更侧重于自定义类型的函数的返回值,表达式的返回值)。
当构造传左值,就走拷贝构造,当构造传右值,就走移动构造。
对于左值,我们后续还要使用,所以只能进行深拷贝,完成拷贝构造。
但对于右值(将亡值),可以直接进行资源的交换,将this和将亡值交换资源。
所以,回到函数传返回值的问题:
在 有了移动构造以后,再经过编译器的优化,就可以做到直接移动构造(资源的交换),实现0拷贝,效率极高!!
2.移动赋值
第一种情况是针对拷贝构造的情况,接下来是针对赋值拷贝的情况:
赋值拷贝同理可得: