C++ 没有移动语义的唯一所有权(auto_ptr)
示例
注意:std::auto_ptr已在C++11中弃用,并将在C++17中删除。仅当您被迫使用C++03或更早版本并且愿意小心时,才应使用此功能。建议与一起移动到unique_ptrstd::move以替换std::auto_ptr行为。
在拥有std::unique_ptr语义之前,我们有了std::auto_ptr。std::auto_ptr提供唯一的所有权,但在复制时转让所有权。
与所有智能指针一样,std::auto_ptr自动清除资源(请参阅RAII):
{
std::auto_ptr<int> p(new int(42));
std::cout << *p;
} //p在这里删除,没有内存泄漏但只允许一个所有者:
std::auto_ptr<X> px = ...; std::auto_ptr<X> py = px; //px现在为空
这允许使用std::auto_ptr来使所有权明确且唯一,以防止意外失去所有权:
void f(std::auto_ptr<X> ) {
//承担X的所有权
//在范围末尾将其删除
};
std::auto_ptr<X> px = ...;
f(px); //f获得基础X的所有权
//px现在为空
px->foo(); //NPE!
//px。〜auto_ptr()不会删除所有权转移发生在“副本”构造函数中。auto_ptr的副本构造函数和副本赋值运算符通过非const引用获取其操作数,以便可以对其进行修改。一个示例实现可能是:
template <typename T>
class auto_ptr {
T* ptr;
public:
auto_ptr(auto_ptr& rhs)
: ptr(rhs.release())
{ }
auto_ptr& operator=(auto_ptr& rhs) {
reset(rhs.release());
return *this;
}
T* release() {
T* tmp = ptr;
ptr = nullptr;
return tmp;
}
void reset(T* tmp = nullptr) {
if (ptr != tmp) {
delete ptr;
ptr = tmp;
}
}
/* other functions ... */
};这破坏了复制语义,复制语义要求复制对象使您拥有两个等效版本。对于任何可复制的类型,T我应该能够写出:
T a = ...; T b(a); assert(b == a);
但是对于auto_ptr,情况并非如此。结果,将auto_ptrs放入容器中是不安全的。