曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 3570|回复: 0
打印 上一主题 下一主题

auto_ptr 的所有权概念

[复制链接]

716

主题

734

帖子

2946

积分

超级版主

Rank: 9Rank: 9Rank: 9

积分
2946
跳转到指定楼层
楼主
发表于 2014-1-9 22:56:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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 :
  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 里被摒弃的原因之一。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-4-30 11:50 , Processed in 0.073761 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表