2015-02-24 50 views
1

据我所知,auto_ptr不能与矢量一起使用,因为auto_ptr不符合作为可复制构造的要求。由于被复制的auto_ptr被修改,因此复制不会导致两个完全相同的副本,从而违反了可复制构造方式。为什么unique_ptr可以用于std容器,vector <>例如?

Unique_ptr也似乎也这样做;它修改被复制的对象 - 被复制对象的指针成员被设置为nullptr。 那么,怎么可能使用uinque_ptr与矢量而不是auto_ptrs?

我的理解是否正确或我在这里错过了什么?

auto_ptr <int> autoPtr(new int); 
vector < auto_ptr <int> > autoVec; 
autoVec.push_back(autoPtr);   //compiler error..why? 

unique_ptr <int> uniquePtr(new int); 
vector < unique_ptr <int> > uniqueVec; 
uniqueVec.push_back(std::move(uniquePtr)); //okay..why? 
+3

[所以你不能复制它](http://coliru.stacked-crooked.com/a/495f091f798712ab),[但你可以移动它](http://coliru.stacked-crooked.com/ a/361fc294fb13279d) – 2015-02-24 05:01:16

+0

@VxxGxx这只是'auto_ptr'不能提供任何防止被尝试复制清除的保护。此外,'auto_ptr'已弃用。不过,这至少会给你一个警告。 – 2015-02-24 06:34:03

+0

@BryanChen我们可以拷贝(通过auto_ptr中的非const引用)或者移动它(通过右值引用),被拷贝的对象被改变。这违反了复制构造的习惯用法。那么是什么让unique_ptr适合像vector这样的容器而不是auto_ptr? – Vishal 2015-02-24 08:18:35

回答

2

auto_ptr的问题在于不希望修改对象的操作确实修改了它。复制构造函数修改了源代码。

unique_ptr没有拷贝构造函数。它有一个移动构造函数。移动构造函数也修改源代码,但这是预期的,并且泛型代码可以区分使用复制构造函数的情况和使用移动构造函数的情形。

vector(以及其他容器)在写入后不会神奇地与unique_ptr一起工作。他们必须更新,以便他们可以使用移动类型。这是在C++ 11中完成的。有可能进行此修改,因为移动和复制是不同的操作。这是不可能的auto_ptr相同,因为该类有一个奇怪的副本构造函数。

0

编译错误是因为试图修改auto_ptr const&正式参数(通过复制它)在push_back实现中。

而不是

autoVec.push_back(autoPtr); 

你可以做

autoVec.emplace_back(autoPtr.release()); 

或者更直接(不使用autoPtr变量)

autoVec.emplace_back(new int(42)); 

然而,尽管这部作品在技术意义上(免责声明:代码甚至没有被任何编译器浏览)你仍然有的问题项目由于尝试复制而自行归零。所以这一切都非常非常不安全。此外,auto_ptr已在C++ 11中弃用;我不知道它现在是否完全被删除,但这不是不可能的。

相关问题