C++11移动语义特性
-
移动语义的必要性
C++11中将数据分为左值和右值。左值为分配内存地址存储在内存中的值。右值为存储在寄存器中但不分配内存地址的值。所以左值可以取地址而右值不可以取地址。
对于右值对象来说,想要将右值对象存放在容器或数组中会发生:根据右值构造新左值对象->销毁右值对象->将新产生的左值对象存放到容器中。为了简化这个过程的时间空间开销引进移动语义。 -
移动语义特性
移动语义是指进行左值右值的赋值控制操作时,不为新的左值对象新开辟空间,不回收右值已经开辟的堆空间,通过浅拷贝和置空操作重复利用已有空间,减少时间空间的资源开销。对于一般const &来说,不能区分是左值引用还是右值引用,所以引入右值引用。右值引用只能绑定到右值不能绑定到左值,可以作为区分右值左值参数的工具。 -
移动构造函数和移动赋值函数
编译器对具有右值的赋值控制函数具有更高的优先级,当发生冲突时优先调用。
//使用右值引用的移动构造函数
//class String
//在rhs 维护的堆空间指针执行delete 操作之前进行转移操作,即移动语义
String (Stirng &&rhs)
:_data(rhs._data){
rhs._data = nullptr;
}
//移动赋值函数
//if 判断必要,存在 s1 = std::move(s1);操作,将左值显式的转换为右值,但是使用std::move函数不代表s1对象生命周期结束,之后依然可以被赋值并进行其他操作。
String& operator=(Stirng && rhs){
if(this != &rhs){
delete[]_data;
_data = rhs._data'
rhs_data = nullptr;
}
return *this;
}
- char*移动语义特殊性
右值对象在所在的语句执行后经行销毁,右值对象所维护的指针也将被置为空指针。其中char 特殊性表现为置为nullptr之后不能进行输出,而其他类型指针如int 经行输出程序不会报错。