为什么unique_ptr可以与std容器一起使用,向量<>例如?

时间:2015-02-24 04:57:15

标签: c++ vector unique-ptr auto-ptr

我知道auto_ptr不能与向量一起使用,因为auto_ptr不符合可复制构造的要求。由于复制的auto_ptr被修改,因此复制不会导致两个完全复制,从而违反了可复制构造的习惯用法。

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?

2 个答案:

答案 0 :(得分:2)

auto_ptr的问题在于,不期望修改对象的操作会对其进行修改。复制构造函数修改了源。

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

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

答案 1 :(得分: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中不推荐使用auto_ptr;我不知道现在是否完全删除了,但这并非不可能。