Possible Duplicate:
What is a smart pointer and when should I use one?
我正在阅读 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;
}
我在文章中唯一不明白的是这句话:
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 中 boost::scoped_ptr
的等价物是 const std::unique_ptr
。这是因为将其设为 const
会阻止任何移动,因此所有权无法转移。
通过示例可以轻松了解所有权语义的重要性。假设您正在使用一个邪恶的开发人员的库,并且它有一个您不知道其实现的功能,例如:
cat* foo();
你知道这个函数返回一个指向 cat
的指针。但是,它是一个原始指针。您不知道是否应该在某个时候销毁猫(使用 delete
),或者库是否会为您做这件事。您甚至不知道该对象是否实际上是动态分配的。您不知道库是否仍然保留 cat
。在过去,如果你有这样的功能,你需要查阅文档才能知道该怎么做。然而,既然我们除了原始指针之外还有智能指针,原始指针有它们自己的所有权语义——它们中最宽松的。它说:“你最好相信我,只要你传递这只cat
,我就会一直有效,但我会是管理它的人。不要把它放得太久。”
然而,一个聪明善良的库开发人员现在会像这样编写这个函数:
std::unique_ptr<cat> foo();
那么这有什么帮助呢?嗯,std::unique_ptr
告诉你很多。它告诉您该函数正在将 cat
对象的所有权交给您。 cat
现在是您的唯一责任。它也非常有助于为您提供智能指针,因为您无需考虑删除
它。您可以只使用指针,当它超出范围时,该对象将被销毁。或者,如果您愿意,可以将所有权转让给另一个函数。
但这并不意味着只有一个指针永远拥有 cat
的所有权。作为骄傲的新主人,接下来会发生什么取决于您。您决定开始共享您的 cat
的所有权是完全合理的:
std::unique_ptr<cat> up = foo();
std::shared_ptr<cat> sp(up.release());
聪明善良的 foo
库开发人员只告诉了您她的意图。她给了你那只猫
,现在你是主人了。现在您可以提供自己的所有权语义。
这样,boost::scoped_ptr
有点像贪婪的 cat
囤积者,他永远不会与任何人分享 cat
,永远不要把猫送给任何人,并会一直保留到他们死去的那一天。