为现有变量创建boost :: shared_ptr

Bil*_*ham 29 c++ boost smart-pointers shared-ptr

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

int a = 3;
Run Code Online (Sandbox Code Playgroud)

我现在如何才能创建一个boost::shared_ptra?例如:

boost::shared_ptr< int > a_ptr = &a; // this doesn't work
Run Code Online (Sandbox Code Playgroud)

111*_*111 44

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

int *a=new int;
boost::shared_ptr<int> a_ptr(a);
Run Code Online (Sandbox Code Playgroud)

那说你绝对不希望将堆栈变量放入shared_ptr中,但是会发生这样的事情

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

int a=9;
boost::shared_ptr<int> a_ptr=boost::make_shared(a);
Run Code Online (Sandbox Code Playgroud)

看这里:

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);
Run Code Online (Sandbox Code Playgroud)


Omn*_*ous 33

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

int a = 3;
::boost::shared_ptr< int > a_ptr(&a); // DO NOT DO THIS!
Run Code Online (Sandbox Code Playgroud)

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

int a = 3;
delete &a;
Run Code Online (Sandbox Code Playgroud)

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

您有两种方法来处理此问题.一个是创建可以删除的东西.另一个是确保shared_ptr实际上不删除它指向的东西.各有利弊.

制作可以删除的内容:

优点:

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

缺点:

  • 有点慢,因为它将涉及堆分配或两个.
  • 结果shared_ptr将引用一个副本,因此修改a将不会反映在它指向的事物的值中.

怎么做:

::boost::shared_ptr<int> a_ptr(::boost::make_shared(a));
Run Code Online (Sandbox Code Playgroud)

这非常相似(这也可以):

::boost::shared_ptr<int> a_ptr(new int(a));
Run Code Online (Sandbox Code Playgroud)

但它的效率稍高.::boost::make_shared在连续内存中分配引用计数和对象可以节省一些魔力,从而节省了对分配器的调用并提高了引用的局部性.

这样shared_ptr做实际上并没有删除它指向的内容:

优点:

  • 更快,但它仍然涉及引用计数的堆分配
  • 直接解决手头的问题(你指向的东西不能删除).
  • shared_ptra,所以如果你改变通过指针访问它的价值的东西会看到新的价值.

缺点:

  • 需要了解更多有关如何shared_ptr工作的信息,这意味着阅读代码的人也必须知道.
  • 如果你所指向的东西在所有shared_ptr指向它之前超出了范围,那么这些指针就会变得晃来晃去,这很糟糕.
  • 前一点使这成为一个非常危险的解决方案.我一般会避免它.

怎么做:

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

void do_nothing_deleter(int *)
{
    return;
}
Run Code Online (Sandbox Code Playgroud)

然后在功能中:

int a = 3;
::boost::shared_ptr a_ptr(&a, do_nothing_deleter);
Run Code Online (Sandbox Code Playgroud)


Luc*_*ton 16

你写的东西不会起作用,因为shared_ptr你正在寻找的构造函数是explicit,所以你需要这样写

boost::shared_ptr<int> a_ptr(&a); // Don't do that!
Run Code Online (Sandbox Code Playgroud)

这个问题然而,就是delete将上存储的值调用a_ptr.由于在您的示例中a具有自动存储持续时间,因此非常糟糕.所以我们也传递了一个自定义删除器:

boost::shared_ptr<int> a_ptr(&a, noop_deleter);
Run Code Online (Sandbox Code Playgroud)

的实现noop_deleter为C++ 11:

auto noop_deleter = [](int*) {};
Run Code Online (Sandbox Code Playgroud)

C++ 03版:

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

  • 虽然这是一个有趣的信息,但我强烈建议不要这样做.使用shared_ptr这一事实是因为您不知道对象何时会被销毁.但是你知道对象在堆栈上会持续多长时间.因此,即使您确切知道它何时会被破坏,也没有必要这样做,因为您总是可以分配回堆栈变量. (2认同)

Lal*_*and 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
Run Code Online (Sandbox Code Playgroud)

请注意,您需要包含<boost/make_shared.hpp>make_shared.