文章转载自:https://blog.csdn.net/k346k346/article/details/81478223
auto_ptr 是STL中智能指针家族的成员(auto_ptr、unique_ptr_、share_ptr、week_ptr)之一,由C++98引入,定义在头文件<memory>。其功能和用法类似于unique_ptr,由 new expression 获得对象,在 auto_ptr 对象销毁时,他所管理的对象也会自动被 delete 掉。
auto_ptr从C++98使用至今,但是从C++11开始,就被unique_ptr替换掉了。
但是为何从C++11开始,引入unique_ptr来替代auto_ptr呢?原因主要有如下几点:
(1)基于安全考虑
先来看下面的赋值语句:
auto_ptr< string> ps (new string ("I reigned lonely as a cloud.”);
auto_ptr<string> vocation;
vocaticn = ps;
上述赋值语句将完成什么工作呢?如果ps和vocation是常规指针,则两个指针将指向同一个string对象。这是不能接受的,因为程序将试图删除同一个对象两次,一次是ps过期时,另一次是vocation过期时。要避免这种问题,方法有多种:
(1)定义陚值运算符,使之执行深复制。这样两个指针将指向不同的对象,其中的一个对象是另一个对象的副本,缺点是浪费空间,所以智能指针都未采用此方案。
(2)建立所有权(ownership)概念。对于特定的对象,只能有一个智能指针可拥有,这样只有拥有对象的智能指针的析构函数会删除该对象。然后让赋值操作转让所有权。——这就是用于auto_ptr和unique_ptr 的策略,但unique_ptr的策略更严格。
(3)创建智能更高的指针,跟踪引用特定对象的智能指针数。这称为引用计数。例如,赋值时,计数将加1,而指针过期时,计数将减1,。当减为0时才调用delete。——这是shared_ptr采用的策略。
当然,同样的策略也适用于复制构造函数,即auto_ptr<string> vocation(ps)时也需要上面的策略。每种方法都有其用途,但为何要摒弃auto_ptr呢?
下面举个例子来说明。
#include <iostream>
#include <string>
#include <memory>
using namespace std;
int main()
{
auto_ptr<string> films[5] ={
auto_ptr<string> (new string("Fowl Balls")),
auto_ptr<string> (new string("Duck Walks")),
auto_ptr<string> (new string("Chicken Runs")),
auto_ptr<string> (new string("Turkey Errors")),
auto_ptr<string> (new string("Goose Eggs"))
};
auto_ptr<string> pwin;
pwin = films[2]; // films[2] loses ownership. 将所有权从films[2]转让给pwin,此时films[2]不再引用该字符串从而变成空指针
cout << "The nominees for best avian baseballl film are\n";
for(int i = 0; i < 5; ++i)
{
cout << *films[i] << endl;
}
cout << "The winner is " << *pwin << endl;
return 0;
}
运行下发现程序崩溃了,原因在上面注释已经说的很清楚,films[2]已经是空指针了,下面输出访问空指针当然会崩溃了。
下一篇—C++11中的智能指针将会给出崩溃的解决方案。