C++ Primer 5th笔记(chap 13 拷贝控制)移动构造和移动赋值
生活随笔
收集整理的这篇文章主要介绍了
C++ Primer 5th笔记(chap 13 拷贝控制)移动构造和移动赋值
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
1. 移动构造函数和移动赋值运算符
一般来说,拷贝一个资源会导致一些额外的开销。在这种拷贝并非必要的情况下,定义了移动构造函数和移动赋值运算符的类就可以避免此问题。
eg.
eg2.
class HasPtr{ public:HasPtr(HasPtr &&p) noexcept:ps(p.ps),i(p.i){p.ps = 0}HasPtr& operator=(HasPtr rhs){swap(*this,rhs);return *this;} };hp = hp2;//hp2 是一个左值;hp2 通过拷贝构造函数来拷贝 hp = std::move(hp2);//移动构造函数来移动hp21.1 异常相关
- noexcept通知标准库不抛出异常可以节省一些额外的操作。
- vector 在调用 push_back 可能会要求为 vector 重新分配内存,重新分配内存的过程可能会发生异常,因此push_back一般调用拷贝构造函数。 除非 vector 知道移动构造函数不会发生异常。
1.2 移后源对象的状态
从一个对象移动数据并不会销毁对象,但有时希望移动操作之后源对象被销毁。当编写一个移动操作后,源对象的状态为:
- 进入一个可析构的安全状态(对象中留下的值是个未知数)
- 对象仍然有效(可以安全地为其赋予新值或可以安全地使用而不依赖当前的值)
2. 更新三五法则
如果一个类定义了任何一个拷贝操作,它就应该定义所有的五个操作。如前所述,某些类必须定义拷贝构造函数、拷贝赋值运算符和析构函数才能正确工作。这些类通常拥有一个资源,而拷贝成员必须拷贝此资源。
3. 删除函数
移到操作一般不会隐式地被编译器定义为删除函数,除非以下情形:
- 与拷贝构造函数不同,移动构造函数被定义为删除函数的条件是:有类成员定义了自己的拷贝构造函数且未定义移动构造函数,或者是有类成员未定义自己的拷贝构造函数并且编译器也不能为其合成移动构造函数。移动赋值运算符的情况类似。
- 如果有类成员的移动构造函数或移动赋值运算符被定义为删除的或者是不可访问的,则类的移动构造函数或移动赋值运算符被定义为删除的。
- 类似拷贝构造函数,如果类的析构函数被定义为删除的或不可访问的,则类的移动构造函数被定义为删除的。
- 类似拷贝赋值运算符,如果类的成员是 const 或是引用类型,则类的移动赋值运算符被定义为删除的。
eg.
//假定Y是一个类,他定义了自己的拷贝构造函数,但未定义自己的移动构造函数 struct hasY{hasY() = default;hasY(hasY &&) = default;Y mem;//hasY将有一个删除的移动构造函数 };hasY hy,hy2 = std::move(hy);//错误,移动构造函数是删除的4. 移动迭代器
make_move_iterator 将一个普通迭代器转化为一个移到迭代器。
void StrVec::reallocate() {// we'll allocate space for twice as many elements as the current sizeauto newcapacity = size() ? 2 * size() : 1;// allocate new memoryauto newdata = alloc.allocate(newcapacity);// move the data from the old memory to the newauto dest= uninitialized_copy(make_move_iterator(begin()),make_move_iterator(end()),newdata); /*auto dest = newdata; // points to the next free position in the new arrayauto elem = elements; // points to the next element in the old arrayfor (size_t i = 0; i != size(); ++i)alloc.construct(dest++, std::move(*elem++)); */free(); // free the old space once we've moved the elements// update our data structure to point to the new elementselements = newdata;first_free = dest;cap = elements + newcapacity; }总结
以上是生活随笔为你收集整理的C++ Primer 5th笔记(chap 13 拷贝控制)移动构造和移动赋值的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: C++ Primer 5th笔记(cha
- 下一篇: C++ Primer 5th笔记(cha