我正在阅读an article,我找到了一个小例子来演示使用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
,表示不打算或不允许所有权转移。
作为这个主题的初学者,这可能是错误的文章,但上述内容究竟意味着什么?
答案 0 :(得分:18)
大多数智能指针拥有他们所指向的对象的所有权 - 他们负责在时机成熟时销毁该对象。但是,不同的智能指针具有不同的所有权语义。也就是说,它们告诉用户该智能指针如何转移所有权,如何在对象之间共享,何时应删除对象等等。使用某个智能指针描述了关于该对象所有权的 intent 。所有权可以转移到其他功能或对象。
boost::scoped_ptr
具有非常严格的所有权语义。它根本不允许任何所有权转让。它通过不可复制来实现这一点(所以你不能通过值将它传递给另一个函数)。
另一个例子,std::unique_ptr
也相当严格。它的特殊能力是可以从中移动。将std::unique_ptr
作为右值传递给函数将使该函数窃取对象的所有权。原始std::unique_ptr
立即失去了所有权。这确保了所有权仅由std::unique_ptr
一个人持有。
C ++ 11中等效于boost::scoped_ptr
的是const std::unique_ptr
。这是因为使const
阻止任何移动,因此无法转移所有权。
通过示例,一种简单的方法来了解所有权语义的重要性。假设您正在使用邪恶的开发人员库,并且它具有您不了解其实现的功能,例如:
cat* foo();
您知道此函数会返回指向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_ptr
有点像贪婪的cat
囤积者,永远不会与任何人分享cat
,永远不会将猫交给任何人,并将其保留至他们死的那一天。