scoped_ptr所有权

San*_*996 9 c++ smart-pointers

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

我正在阅读一篇文章,我找到了一个小例子来证明使用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;
}
Run Code Online (Sandbox Code Playgroud)

我在文章中唯一不理解的是这句话:

使用时scoped_ptr,表示不打算或不允许所有权转移.

也许作为这个主题的初学者开始是错误的文章,但上述内容究竟意味着什么呢?

Jos*_*eld 18

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

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

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

相当于boost::scoped_ptr在C++ 11中是一个const std::unique_ptr.这是因为它const可以防止任何移动,因此无法转移所有权.

通过示例,一种简单的方法来了解所有权语义的重要性.假设您正在使用邪恶的开发人员库,并且它具有您不知道其实现的功能,例如:

cat* foo();
Run Code Online (Sandbox Code Playgroud)

你知道这个函数返回一个指向a的指针cat.但是,它是一个原始指针.你不知道你是否应该delete在某些时候摧毁猫(或),或者图书馆会为你做这件事.您甚至不知道该对象是否实际上是动态分配的.你不知道图书馆是否仍然掌握着cat.过去,如果您有这样的功能,则需要查找文档以了解要执行的操作.但是,既然我们除了原始指针之外还有智能指针,原始指针也有自己的所有权语义 - 这些都是最轻松的.它说:"你最好相信我,cat只要你传递它,我保持这个有效,但我会成为管理它的人.不要把它保留太长时间."

但是,一个聪明而善良的库开发人员现在会像这样编写这个函数:

std::unique_ptr<cat> foo();
Run Code Online (Sandbox Code Playgroud)

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

这并不意味着只有一个指针才能拥有所有权cat.作为骄傲的新主人,您可以自行决定接下来会发生什么.您决定要开始分享您的所有权是完全合理的cat:

std::unique_ptr<cat> up = foo();
std::shared_ptr<cat> sp(up.release());
Run Code Online (Sandbox Code Playgroud)

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

通过这种方式,a boost::scoped_ptr有点像贪婪的cat囤积者,永远不会cat与任何人分享,永远不会把猫交给任何人,并且会保留它直到他们死去的那一天.