<unique_ptr> 使用push_back调整矢量大小 - 它是如何工作的?

vector<unique_ptr> resizing with push_back - how does it work?

本文关键字:何工作 工作 gt ptr unique lt 使用 push 调整 back      更新时间:2023-10-16

据我了解,当东西被pushed_back到向量中时,有时它必须分配一个新的内存块,导致将所有元素从旧内存块复制到其中,调用它们的析构函数。既然unique_ptr析构函数会删除拥有的内存,那么它们怎么可能与 vector 一起使用?在载体中使用unique_ptr安全吗?它比常规指针慢吗?

导致将所有元素从旧内存块复制到其中,调用它们的析构函数。既然unique_ptr析构函数会删除拥有的内存,那么它们怎么可能与 vector 一起使用?

事实上,它不再是严格复制元素,而是在移动。对于没有隐式或显式移动构造函数的类型,这是相同的。但对于unique_ptr来说,这意味着新的unique_ptr是在新分配的内存中构造的,给定对"旧"unique_ptr s的重值引用。他们的移动构造函数做了正确的事情,即它将所有权从旧unique_ptr转移到新,将旧的留空,因此在它们被销毁时不会删除任何内容。

在载体中使用unique_ptr安全吗?

只要

您尊重语言规则和"C++常识",就可以在任何地方使用unique_ptr。这意味着,您必须明确地做愚蠢的事情来破坏unique_ptr的安全行为。其中包括例如假装将拥有对象的所有权交给另一个智能指针:

unique_ptr<T> ptr1 {new T()};
unique_ptr<T> ptr2 {ptr1.get()}; //two unique_ptr's owning the same object...

或一些涉及reinterpret_castmemcpymemset或其他不尊重对象生存期C++内容的破坏性行为。

它比常规指针慢吗?

或。与复制原始指针(即将原始指针设置为零(相比,移动unique_ptr显然涉及一些小开销。但是,是否可以优化该开销取决于您的编译器和优化器。与性能一样,请咨询探查器以评估性能是否变慢以及速度减慢是否重要。我敢打赌它不会,考虑到智能指针会给你带来的安全性,永远不要问unique_ptr的性能。

旁注:如果您事先知道矢量的大小,请记住使用 vector::reserve() .它将为您节省unique_ptr的重新分配和移动。如果你只知道你的矢量的近似大小,不要小气 - unique_ptr不是很大(通常和原始指针加上删除器一样大,可能会也可能不会被优化掉(,所以保留百分之几不会有什么坏处,除非你真的有严格的内存限制。

使用移动语义,可以将unique_ptr从一个位置移动到另一个位置。这将避免指针在从一个内存位置"移动"到另一个内存位置时std::move存储的数据被破坏。

这有点像随着矢量的增长执行从旧矢量数组到新内存位置的浅拷贝。

根据 cpp首选项,std::unique_ptr 的一个用例是在"移动感知容器"中使用,例如 std::vector 。这意味着std::vector<T>足够聪明,可以检测T何时可移动,std::unique_ptr就是这种情况,并在调整矢量大小时使用移动构造函数。