为现有变量创建boost :: shared_ptr

时间:2011-12-11 18:43:46

标签: c++ boost shared-ptr smart-pointers

我有一个现有的变量,例如

int a = 3;

我现在如何创建boost::shared_ptra?例如:

boost::shared_ptr< int > a_ptr = &a; // this doesn't work

4 个答案:

答案 0 :(得分:43)

虽然您应该将变量放入其创建的托管指针中,以便从现有指针执行此操作。

int *a=new int;
boost::shared_ptr<int> a_ptr(a);

那说你绝对不想把堆栈变量放到shared_ptr中会发生什么事情会发生

如果由于某种原因某个函数需要shared_ptr并且你只有一个堆栈可变,你最好这样做:

int a=9;
boost::shared_ptr<int> a_ptr=boost::make_shared(a);

见这里:

http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/make_shared.html

还值得注意的是,如果你能够使用,那么shared_ptr是c ++ 11标准。你可以在构建谈话中使用auto和make_shared一样使用Herb Sutter笔记。

#include <memory>

int a=9;
auto a_ptr=std::make_shared(9);

答案 1 :(得分:31)

首先,您有一个错误,因为shared_ptr不会自动从适当类型的指针转​​换。你必须明确说明你想做的事情:

int a = 3;
::boost::shared_ptr< int > a_ptr(&a); // DO NOT DO THIS!

但你有另一个问题。想象一下这段代码的效果:

int a = 3;
delete &a;

在我给出的第一个例子中,这将不可避免地发生,即使它不是那么直接。 shared_ptr存在的全部理由是当所有指向它的东西消失时删除它。当然,这会引起各种奇怪的行为。

您有两种方法可以解决此问题。一种是创建可以删除的内容。另一个是确保shared_ptr实际上没有删除它指向的东西。各有利弊。

制作可以删除的内容:

优点:

  • 简单易行。
  • 您不必担心对象的生命周期。

缺点:

  • 有点慢,因为它将涉及堆分配或两个。
  • 生成的shared_ptr将引用副本,因此对a的修改不会反映在它指向的内容的值中。

怎么做:

::boost::shared_ptr<int> a_ptr(::boost::make_shared(a));

这与(这也有效)相似:

::boost::shared_ptr<int> a_ptr(new int(a));

但效率稍高。 ::boost::make_shared在连续内存中分配引用计数和对象,这可以节省对分配器的调用并提高引用的局部性。

使shared_ptr实际上不删除它指向的内容:

优点:

  • 更快,但它仍然涉及引用计数的堆分配
  • 直接解决手头的问题(您指向的内容无法删除)。
  • shared_ptr引用a,因此如果您更改其值,通过指针访问它的内容将会看到新值。

缺点:

  • 需要更多地了解shared_ptr的工作原理,这意味着阅读代码的人也必须知道。
  • 如果你所指向的东西在所有shared_ptr指向它之前超出了范围,那么那些指针就会变得晃动,那就太糟了。
  • 前一点使其成为非常冒险的解决方案。我一般会避免它。

怎么做:

函数外部的某个地方(可能在匿名命名空间中):

void do_nothing_deleter(int *)
{
    return;
}

然后在函数中:

int a = 3;
::boost::shared_ptr a_ptr(&a, do_nothing_deleter);

答案 2 :(得分:15)

你写的内容不起作用,因为你正在寻找的shared_ptr的构造函数是explicit,所以你需要像这样编写它

boost::shared_ptr<int> a_ptr(&a); // Don't do that!

的问题是delete将在a_ptr的存储值上调用a。由于在您的示例中boost::shared_ptr<int> a_ptr(&a, noop_deleter); 具有自动存储持续时间,因此非常糟糕。所以我们也传递了一个自定义删除器:

noop_deleter

C ++ 11的auto noop_deleter = [](int*) {}; 实现:

// Can't be put in local scope
struct {
    void
    operator()(int*) const
    {}
} noop_deleter;

C ++ 03版:

{{1}}

答案 3 :(得分:8)

您无法为现有变量创建boost :: shared_ptr。存储在boost :: shared_ptr中的项目将在创建时存储。

但是,您可以创建一个boost :: shared_ptr,它是现有变量的副本。

例如

int a = 3; // Existing variable
boost::shared_ptr<int> aCopy = boost::make_shared<int>(a); //Create copy with value of a

请注意,您需要为make_shared添加<boost/make_shared.hpp>