cleanc++05_02 - Move语义与右值引用

Move 语义

什么是Move语义?

简单来说,就是只移动对象的数据,而不需要对原对象进行深拷贝。

Move语义的优势——Move操作符效率比拷贝操作符效率高。

使用方法:

class Clazz{
public:
    Clazz() noexcept;
    Clazz(clazz&& other) noexcept;  // move 构造函数
    Clazz& operator =(clazz&& other) noexcept;  // move赋值运算符
}

noexcept 是C++11 为了替代 throw() 而提出的一个新的关键字,表示被修饰的函数 不允许抛出任何异常

noexcept()括号里面可以接受一个bool值(true、false),或者一个常量表达式,并将常量表达式的结果转换为bool值。true表示函数不会抛出异常,反之则可能抛出异常。

&& 为右值引用

右值引用

什么是右值? c语言中将赋值语句的等号左右两边定义为左值和右值,C++沿用了这个说法,实际上 左值是一个在内存中占有位置的对象,其具有可访问和可识别的内存地址;而右值大多是一些临时对象或者子对象,因此不能给右值赋值。

int sum = 1+2; sum就是左值,而表达式 "1+2"是一个右值,右值在使用时会占有内存,但当执行下条语句时,这块内存就会释放。

由于move语义在c++11之后的引入,通过右值引用就可以得到右值的内存位置。甚至还可以运用指针改变这块内存上的数据。

右值引用可以作为任意函数或者方法的参数,其适用的场景是move构造器和move赋值运算符。

表5-1

表5-2

关于move语义使用的建议:

  1. 大量使用Move语义会降低代码的可读性,而且编译器可能无法执行其优化策略。

  2. move 或多或少是对右值引用对象的一个强制类型转换。

  3. 一个类需要显示定义其析构函数时,总是需要定义拷贝构造、赋值构造函数、move构造器和move赋值运算符。同样的,当这个类不需要显示定义析构函数时,也不要声明或定义拷贝构造、赋值构造函数、move构造器和move赋值运算符;用智能指针来管理资源。

posted @ 2021-11-21 20:23  __冫冫  阅读(63)  评论(0编辑  收藏  举报