C++ 为现有变量创建boost::shared_ptr

C++ 为现有变量创建boost::shared_ptr,c++,boost,shared-ptr,smart-pointers,C++,Boost,Shared Ptr,Smart Pointers,我有一个现有变量,例如 int a = 3; 我现在如何创建一个boost::shared_ptr到a?例如: boost::shared_ptr< int > a_ptr = &a; // this doesn't work boost::shared_ptra_ptr=&a;//这不管用 尽管您应该在创建变量时将变量放入托管指针中,以便从现有指针执行此操作 int *a=new int; boost::shared_ptr<int> a_ptr(a);

我有一个现有变量,例如

int a = 3;
我现在如何创建一个
boost::shared_ptr
a
?例如:

boost::shared_ptr< int > a_ptr = &a; // this doesn't work
boost::shared_ptra_ptr=&a;//这不管用

尽管您应该在创建变量时将变量放入托管指针中,以便从现有指针执行此操作

int *a=new int;
boost::shared_ptr<int> a_ptr(a);
int*a=新的int;
boost::共享\u ptr a \u ptr(a);
也就是说,您肯定不想将堆栈变量放入共享\u ptr中,否则会发生不好的事情 如果出于某种原因,某个函数采用了shared_ptr,而您只有一个堆栈变量,那么最好这样做:

int a=9;
boost::shared_ptr<int> a_ptr=boost::make_shared(a);
inta=9;
boost::shared_ptr a_ptr=boost::make_shared(a);
请看这里:

另外值得注意的是,如果您能够使用c++11标准,那么共享_ptr也在其中。您可以将auto与make_shared结合使用,就像构建对话中的Herb Sutter注释一样

#include <memory>

int a=9;
auto a_ptr=std::make_shared(9);
#包括
INTA=9;
自动a_ptr=std::使_共享(9);

无法为现有变量创建boost::shared\u 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
int a=3;//现有变量
boost::shared_ptr aCopy=boost::make_shared(a)//创建具有

请注意,您需要为make_shared包含

您编写的内容将无法工作,因为您要查找的
shared_ptr
的构造函数是
显式的,所以您需要这样编写

boost::shared_ptr<int> a_ptr(&a); // Don't do that!
C++11的
noop\u deleter
实现:

auto noop_deleter = [](int*) {};
C++03版本:

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

首先,您有一个错误,因为
共享\u ptr
不会自动从适当类型的指针转换。你必须明确说明你想做什么:

int a = 3;
::boost::shared_ptr< int > a_ptr(&a); // DO NOT DO THIS!
在我给出的第一个例子中,这将不可避免地发生,即使它不是那么直接
shared_ptr
存在的全部原因是当所有指向它的指针都消失时删除它。当然,这会导致各种奇怪的行为

处理这个问题有两种方法。一种是创建可以删除的东西。另一个是确保
shared_ptr
不会删除它所指向的内容。每种方法都有利弊

制作可以删除的内容: 优点:

  • 简单易用
  • 您不必担心对象的生命周期
缺点:

  • 有点慢,因为它会涉及一两个堆分配
  • 生成的
    shared\u ptr
    将引用副本,因此对
    a
    的修改不会反映在它所指向的对象的值中
如何做到:

::boost::shared_ptr<int> a_ptr(::boost::make_shared(a));
然后在函数中:

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

这真是一个伟大的知识。我认为其他人的
make_shared
想法更容易处理,但我真的认为这是最好的答案。@Omnifarious:这是唯一正确的答案,因为问题是如何为现有变量创建一个共享的ptr,而不是它的副本。另外,制作
noop\u deleter
模板会更好。虽然这是一条有趣的信息,但我强烈建议不要这样做。使用共享的ptr是因为您不知道对象何时会被销毁。但是,您知道对象将在堆栈上持续多长时间。因此,即使您确切地知道它将在什么时候销毁,也没有必要这样做,因为您总是可以将其赋值回堆栈变量。@111111:有优点也有缺点。这种方法运行的巨大风险是
共享\u ptr
不会在堆栈变量消失之前消失。但这比在堆上创建副本要高效得多。ybungalobill是正确的,这是对上述问题唯一技术上正确的答案。它不应该被否决。@Omnifarious嗯,很公平,事后看来,我也许不应该被否决。但创建共享的_ptr来堆栈变量是一项风险很大的业务。如果您确切知道变量需要多长时间,您可能不会使用共享的\u ptr。因为他知道他希望它能持续多长时间(即当它包含他的答案时,他可以重新分配给堆栈变量。)-如果你编辑答案,我会收回下一票。顺便说一句,我把你的两个答案组合在一起。第一个建议非常危险-当共享的ptr消失时,它会删除指向的对象,即使原始指针仍然存在。在这种情况下,你必须使用不可操作的删除器——见吕克·丹顿的答案。你为什么要做这样的事?@curiousguy,我这样做的原因如下所述;我在堆栈上有一个变量,有一个函数需要一个共享点作为输入参数。我想知道为什么该函数需要一个
shared\u ptr
!啊哈-我使用的是点云库(),整个API都是为使用共享指针而设计的。
::boost::shared_ptr<int> a_ptr(::boost::make_shared(a));
::boost::shared_ptr<int> a_ptr(new int(a));
void do_nothing_deleter(int *)
{
    return;
}
int a = 3;
::boost::shared_ptr a_ptr(&a, do_nothing_deleter);