定义
只是自动帮你调用析构。得自己确保写对这个函数。比如把指针指向清0,让移后源对象达到一个安全的可析构状态。
strVec::strVec(strVec &&) noexcept:elements(s.elements), first_free(s.first_free), cap(s.cap)
{
s.elements = s.first_free = s.cap = nullptr; //不写会释放
}
标记noexcept来告诉容器分配内存采用移动
容器要保证发生异常时对象没有更改,即可以回退。
打个比方,vector的push_back操作可能会重新分配内存,可以用移动构造或拷贝构造。
移动元素的话会改变旧空间的元素,然后抛出异常就会让操作回不去了,这时vector里乱套。即移动抛出异常的话直接完蛋了。
而拷贝构造函数发生异常大不了清除新分配的空间。
如果想让vector通过移动分配内存,就标记为noexcept来告诉编译器可以安全使用。但是你咋知道安全呢?
合成的移动
如果显式定义任何拷贝函数,就不会帮你默认定义移动了。
如果显式定义任何移动函数,就不会帮你默认合成拷贝了。
当然还有好多种把合成移动定义成删除的情况,不研究了。
不用管默不默认了,你敢用默认的吗?
移动和拷贝的协作
1.移动右值,拷贝左值。
2.没移动的话,就用拷贝替代
能用因为Foo &&能转化成 const Foo&