auto_ptr 是智能指针,它有一个(owenship)概念:对于特定的对象,只能有一个智能指针可拥有它。这样一来,只有拥有对象的智能指针的析构函数可以删除对象。赋值操作会转让所有权。unique_ptr 也有类似策略,但比 unique_ptr 更为严格些。
考虑下面这个不适合使用 auto_ptr 的示例:
[C++] 纯文本查看 复制代码 // fowl.cpp -- auto_ptr a poor choice
#include <iostream>
#include <string>
#include <memory>
int main()
{
using namespace std;
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] 丢失所有权
cout << "The nominees for best avian baseball film are\n";
for (int i = 0; i < 5; i++)
cout << *films[i] << endl;
cout << "The winner is " << *pwin << "!\n";
// cin.get();
return 0;
}
当运行该程序时,会出现 Segmentation fault 段错误提示(Linux 环境下,该错误提示形式岁系统而异)。原因正是错误的使用了 auto_ptr :这条语句导致了 films[2] 不再引用该字符串。在 auto_ptr 放弃对象的所有权后,就不能再用它来访问该对象了。当程序打印 films[2] 指向的字符串时,却发现这是个空指针,当然会发生错误。
如果将上面程序中的 auto_ptr 改为 shared_ptr ,那么程序可以正常运行,比如:- shared_ptr <string> pwin;
- pwin = films[2];
复制代码 这样,pwin 和 films[2] 指向了同一个对象,而引用计数从 1 增加到 2 (这是 shared_ptr 的特点)。在程序末尾,后声明的 pwin 首先调用其析构函数,该析构函数将引用计数降到 1.然后,再将 shared_ptr 数组的成员释放,在对 films[2] 调用析构函数时,将引用计数降低到 0,并释放以前分配的空间。
如果 auto_ptr 改为 unique_ptr ,编译器在编译时会直接报告 pwin = films[2]; 这句话的错误,而无需等到程序运行时。这就是说,unique_ptr 比 auto_ptr 严格,也是 auto_ptr 在 C++11 里被摒弃的原因之一。
|