曲径通幽论坛

标题: auto_ptr 的所有权概念 [打印本页]

作者: easy    时间: 2014-1-9 22:56
标题: auto_ptr 的所有权概念
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 << endl;
    cout << "The winner is " << *pwin << "!\n";
    // cin.get();
    return 0;
}

当运行该程序时,会出现 Segmentation fault 段错误提示(Linux 环境下,该错误提示形式岁系统而异)。原因正是错误的使用了 auto_ptr :
  1. pwin = films[2];
复制代码
这条语句导致了 films[2] 不再引用该字符串。在 auto_ptr 放弃对象的所有权后,就不能再用它来访问该对象了。当程序打印 films[2] 指向的字符串时,却发现这是个空指针,当然会发生错误。

如果将上面程序中的 auto_ptr 改为 shared_ptr ,那么程序可以正常运行,比如:
  1. shared_ptr <string> pwin;
  2. 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 里被摒弃的原因之一。





欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) Powered by Discuz! X3.2