12

可能重复:
什么是智能指针,我应该什么时候使用?

我正在阅读一篇文章,我找到了一个小例子来演示boost::scoped_ptr<T>

#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;
}

我在文章中唯一不明白的是这样的声明:

使用scoped_ptr,您表示不打算或不允许所有权转让。

作为该主题的初学者,也许这是错误的文章,但是上面的行到底是什么意思?

4

1 回答 1

19

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

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

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

boost::scoped_ptrC++11 中的等价物是const std::unique_ptr. 这是因为制作它const可以防止任何移动,因此无法转移所有权。

通过示例可以轻松了解所有权语义的重要性。假设您正在使用一个邪恶的开发人员的库,并且它有一个您不知道其实现的函数,例如:

cat* foo();

你知道这个函数返回一个指向 a 的指针cat。但是,它是一个原始指针。您不知道是否应该delete在某个时候销毁猫(使用 ),或者图书馆是否会为您这样做。您甚至不知道该对象是否实际上是动态分配的。你不知道图书馆是否还保留着cat. 过去,如果您有这样的功能,则需要查找文档以了解如何操作。然而,现在我们除了原始指针之外还有智能指针,原始指针有自己的所有权语义——它们中最宽松的。它说:“你最好相信我,cat只要你传递它,我就会保持它的有效性,但我将是管理它的人。不要保存太久。”

然而,一个聪明而善良的库开发者现在会像这样编写这个函数:

std::unique_ptr<cat> foo();

那么这有什么帮助呢?嗯,这std::unique_ptr告诉你很多。它告诉您该函数正在向您放弃该cat对象的所有权。现在cat是您的全部责任。它对给你一个智能指针也很有帮助,因为你不需要考虑delete它。您可以只使用指针,当它超出范围时,对象将被销毁。或者,如果您愿意,您可以将所有权转让给另一个职能部门。

这并不意味着只有一个指针将拥有cat尽管的所有权。作为自豪的新主人,接下来会发生什么由您决定。您决定开始共享您的所有权是完全合理的cat

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

聪明善良的foo图书馆开发者只告诉你她的意图是什么。她给了你cat,现在你是主人。现在您可以提供自己的所有权语义。

这样一来,boost::scoped_ptra有点像一个贪婪的cat囤积者,永远不会cat与任何人分享,永远不会把猫给任何人,并且会一直保存到他们死去的那一天。

于 2013-02-02T01:07:39.807 回答