与C++ 11不同,C++ 98标准库仅提供一个智能指针类auto_ptr,自C++ 11起不推荐使用。它的目标是提供unique_ptr现在所做的语义。
但是auto_ptr引入了一些问题:
- 在设计时,该语言没有针对构造函数和赋值运算符的移动语义。但是,目标仍然是提供所有权转移的语义。结果,复制和赋值运算符具有移动语义,这可能导致严重的麻烦,尤其是在传递auto_ptr作为参数时。
- 没有删除器的语义,因此您只能使用它来处理分配有new的单个对象。
- 因为它最初是C++标准库提供的唯一智能指针,所以经常被滥用,尤其是假设它像类shared_ptr一样提供了共享所有权的语义。
关于意外失去所有权的危险,请考虑以下示例,该示例由一个普通的函数实现组成,该函数打印出auto_ptr所引用的对象:
//坏示例
template <typename T>
void bad_print(std::auto_ptr<T> p) //形参p获得传进来参数的所有权
{
if (p.get() == NULL) {
std::cout << "NULL";
} else {
std::cout << *p;
}
} //函数退出时p将删除与其关联的对象
每当将auto_ptr传递到bad_print()时,它所拥有的对象(如果有)都将被删除,原因是将作为参数传递的auto_ptr的所有权传递给参数p,并且p在函数退出时删除其拥有的对象。 这可能不是程序员的意图,并且会导致致命的运行时错误:
std::auto_ptr<int> p(new int);
*p = 42;
bad_print(p);
*p = 18; //运行时错误
当将auto_ptr传递到容器时,该行为尤其适用。 使用unique_ptr不再可能出现这种错误,因为您必须显式地将参数传递给std::move()。