如何将unique_ptr的向量声明为类数据成员?

How to declare a vector of unique_ptr's as class data member?

本文关键字:声明 数据成员 向量 unique ptr      更新时间:2023-10-16

我想要一个unique_ptr的向量作为我正在创建的类的成员。

class Foo {
    [...]
private:
    vector<unique_ptr<Bar>> barList;
}

但随后我开始从VS2010编译器获得神秘的错误消息:

error C2248: 'std::unique_ptr<_Ty>::operator =' : cannot access private member declared in class 'std::unique_ptr<_Ty>'

除了下面的几条错误线,这些错误线深入探讨了微软对std::_Copy_impl<>的实现。。。

我将会员声明改为

vector<unique_ptr<Bar>>* barList;

它进行编译。但我忍不住想知道,为什么我不能按照我最初想要的方式去做?对于咧嘴笑,我试过这个,效果很好:

vector<Bar> barList;

但现在我失去了unique_ptr的便利性。我想要我的蛋糕,我也想吃!

这里的问题是,在某个地方,您的代码试图调用Foo的"复制赋值"运算符。

这导致编译器尝试生成一个复制赋值运算符,该运算符调用Foo的所有子对象的复制赋值运算符。最终,这导致了复制unique_ptr的尝试,这是不可能的操作。

unique_ptr没有复制语义,因此不能使用任何复制所包含对象的方法。您可以通过在它试图复制的地方使用std::move来对右值引用执行此操作。如果没有看到你的代码,我就不能说它会在哪里。

如果它以第二种形式编译,要么你没有使用相同的代码,要么存在编译器错误。两者都应该以同样的方式失败。

第三个例子,按值存储是最简单的方法,除非您的对象很大并且按值存储/复制成本很高。

通常std::move(iUniquePtr)在某个地方丢失(例如,使用push_back时)。

摘录自www.cplusplus.com

std::unique_ptr::operator=

unique_ptr分配对象获取x内容的所有权,包括存储的指针和存储的删除器(以及在某个时刻删除对象的责任)。unique_ptr对象在调用之前拥有的任何对象都将被删除(就好像调用了unique_ptr的析构函数一样)

但也有一个警告:

本页介绍了C++标准最新修订版(2011年)引入的一项功能。较旧的编译器可能不支持它。

MSVC 2010将operator=定义为私有(不可复制),但支持swap方法。

常见的问题有erase()emplace*()push*()。当一个或多个矢量元素被擦除或插入时,这些将尝试四处移动矢量元素。虽然这应该起作用,但由于std::unique_ptr是可移动的,并且不严格要求移位,所以有时它不起作用,原因是STL实现中的错误。出于这个原因,使用std::list可能会更好,可以使用std::shared_ptr、使用std::vector替代方案、提交错误,或者只使用原始指针,这是一个非常简单有效的解决方案。

不能在vector中使用unique_ptr,因为vector实现强烈依赖于值赋值运算符,该运算符在unique_ptr中是私有的。使用boost中的shared_ptr或C++11中的其他智能ptr实现。