关于c ++:scoped_ptr所有权

scoped_ptr ownership

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
What is a smart pointer and when should I use one?

我读了一篇文章,找到了一个小例子来演示boost::scoped_ptr的用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <cstdlib>
#include <iostream>
#include <boost/scoped_ptr.hpp>
#include <boost/scoped_array.hpp>

static int count = 0;

class printer
{
    int m_id;

public:
    printer(void) :
        m_id(count++)
    {
    }

    ~printer(void)
    {
        std::cout <<"Printer" << m_id
                  <<" destroyed" << std::endl;
    }
};

int
main(void)
{
    boost::scoped_ptr<printer> p1(new printer);
    boost::scoped_ptr<printer> p2(new printer);
    std::cout <<"Exiting test program" << std::endl;

    return EXIT_SUCCESS;
}

这篇文章中我唯一不明白的是这句话:

using scoped_ptr, you indicate that ownership transfer is not intended or allowed.

也许这篇文章从一个初学者的角度出发是错误的,但是上面这一行到底意味着什么呢?


大多数智能指针都拥有指向的对象的所有权——它们负责在时间到来时销毁该对象。然而,不同的智能指针具有不同的所有权语义。也就是说,它们告诉智能指针的用户,所有权可以或不可以被转移,如何在对象之间共享,何时应该删除对象,等等。使用某个智能指针描述您对该对象所有权的意图。所有权可以转移到其他功能或对象。

boost::scoped_ptr具有非常严格的所有权语义。它根本不允许任何所有权转让。它通过不可复制来实现这一点(因此不能通过值将其传递给另一个函数)。

另一个例子是,std::unique_ptr也相当严格。它的特殊能力是它可以被移动。将std::unique_ptr作为右值传递给函数将使该函数窃取对象的所有权。原来的std::unique_ptr立即失去所有权。这确保所有权仅由一个std::unique_ptr持有。

在C++ 11中等效于EDCOX1〔0〕是EDCOX1〔6〕。这是因为使之成为const可防止任何移动,因此所有权不能转移。

通过一个例子,可以很容易地看出所有权语义有多重要。假设您使用的是一个邪恶的开发人员库,它具有一个您不知道实现的功能,例如:

1
cat* foo();

您知道这个函数返回一个指向cat的指针。但是,它是一个原始指针。你不知道你是否应该在某个时候销毁这只猫(和delete一起),或者图书馆是否会为你做这件事。您甚至不知道对象是否是动态分配的。你不知道图书馆是否还保留着cat。在过去,如果您有这样一个函数,那么您需要查找文档以了解要做什么。然而,现在我们除了原始指针之外还有智能指针,原始指针有自己的所有权语义——这是所有指针中最轻松的。上面写着:"你最好相信我,只要你把这本书传出去,我就把它保存在有效期内,但我会负责管理的。别留太久。"

然而,一个聪明善良的库开发人员现在可以这样编写这个函数:

1
std::unique_ptr<cat> foo();

那么这有什么帮助呢?好吧,江户记[1]告诉你很多。它告诉您,该函数正在向您放弃cat对象的所有权。江户一号〔8〕现在是你的唯一责任。这对给你一个聪明的指针也很有帮助,因为你不需要考虑使用delete。您只需使用指针,当它超出范围时,对象就会被销毁。或者,如果您愿意,您可以将所有权转移到另一个函数。

但这并不意味着只有一个指针拥有cat的所有权。作为一个引以为豪的新主人,接下来会发生什么由你决定。你决定开始分享你的cat的所有权是完全合理的:

1
2
std::unique_ptr<cat> up = foo();
std::shared_ptr<cat> sp(up.release());

聪明善良的foo库开发人员只告诉你她的意图。她给了你一辆cat,现在你成了主人。现在您可以提供自己的所有权语义。

这样的话,一个江户〔0〕有点像一个贪婪的江户〔8〕囤积者,他永远不会和任何人分享江户〔8〕的东西,永远不会把猫给任何人,也不会把猫留到他们死的那天。