对象移动
作者:互联网
对象移动是相对于对象拷贝的,在一些场景(比如:把对象作为一个参数传递)移动会比拷贝提升性能。还有一个原因是有些对象禁止拷贝:例如IO类和unique_ptr。
被移动的对象必须是右值,如果不是可以用std::move()显式转换为右值,但转换之后不能对这个对象的值做任何假设,最好手动清空。
对移动操作的定义最好是noexcept
的,因为标准库容器比如vector在push_back
的过程中有可能会重新分配内存,需要将原来的对象拷贝或者移动到新内存。如果移动过程是有可能出现异常的话,那移动到一半出了异常,而前边移动的对象的值都改变了(移动之后不能对被移动的对象的值做任何假设),使得vector无法恢复成push_back
前的样子。所以移动构造函数如果没有noexcept
,vector会优先使用拷贝构造函数。
C++ primer的例子:
class StrVec{
public:
StrVec(StrVec &&) noexcept;
};
StrVec::StrVec(StrVec &&s) noexcept : /*成员初始化器*/
{ //构造函数体 }
如果类的对象都是可移动的而且这个类没有定义拷贝构造函数,operator= 和 析构函数,那编译器会为这个类合成移动构造函数。
class B{
public:
string s = "s";
};
int main()
{
B b;
B a = b;
cout << a.s<< b.s << endl;
return 0;
}
//输出为两个s
int main()
{
B b;
B a = std::move(b);
cout << a.s<< b.s << endl;
return 0;
}
//输出为一个s,b的s被移动给了a
标签:对象,noexcept,StrVec,拷贝,移动,构造函数 来源: https://www.cnblogs.com/hellozhangjz/p/16285539.html