Vit*_*meo 7 c++ memory smart-pointers vector c++11
据我所知,当把东西推回到向量中时,有时它必须分配一个新的内存块,导致从旧内存块中复制所有元素,调用它们的析构函数.由于unique_ptr析构函数删除了拥有的内存,它们如何使用向量?在向量中使用unique_ptr是否安全?它比常规指针慢吗?
Arn*_*rtz 12
导致从旧内存块中复制所有元素,调用它们的析构函数.由于unique_ptr析构函数删除了拥有的内存,它们如何使用向量?
实际上,它不再严格地复制元素,它正在移动.对于没有隐式或显式移动构造函数的类型,它们是相同的.但是对于unique_ptrs来说,这意味着,新的unique_ptrs是在新分配的内存中构造的,给出了对"旧" unique_ptr的rvalue引用.他们的移动构造函数做了正确的事情,即它将所有权从旧的转移到新unique_ptr的,将旧的所有权留空,因此当它们被销毁时不会被删除.
在向量中使用unique_ptr是否安全?
这是保存使用unique_ptr小号无处不在,只要你尊重语言规则和"C++常识".这意味着,你必须明确地做一些愚蠢的事情来打破unique_ptr安全行为.其中包括假装将拥有的对象的所有权赋予另一个智能指针:
unique_ptr<T> ptr1 {new T()};
unique_ptr<T> ptr2 {ptr1.get()}; //two unique_ptr's owning the same object...
Run Code Online (Sandbox Code Playgroud)
或者一些破坏性的行为涉及reinterpret_cast,memcpy,memset或不尊重C++对象生存其他的东西.
它比常规指针慢吗?
也许.unique_ptr与复制原始指针相比,移动a时显然有一些小的开销,即将原始设置为零.但是,是否可以优化开销取决于您的编译器和优化器.与性能一样,请咨询您的探查器,以评估它是否更慢以及减速是否重要.我打赌它不会,并考虑到智能指针给你的安全性,只是从不询问unique_ptr性能.
旁注:如果您事先知道矢量的大小,请记住使用vector::reserve().它将为您节省unique_ptrs 的重新分配和移动.如果你只知道你的矢量的大小,不要小 - unique_ptrs不是很大(通常和原始指针一样大,还有删除器,可能会也可能不会被优化),所以保留一些除非你真的有严格的内存限制,否则不会受到更多伤害.
使用移动语义,可以将unique_ptr从一个位置移动到另一个位置.这将避免在指针std::move从一个存储位置"移动" 到另一个存储位置时对指针保持的数据的破坏.
它有点像向量增长时从旧向量数组到新内存位置执行浅复制.
根据cppreference,其用例之一std::unique_ptr是在“移动感知容器”中使用,例如std::vector. 这意味着std::vector<T>足够智能T,可以检测何时可移动(即 的情况)std::unique_ptr,并在调整向量大小时使用移动构造函数。