首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >创建现有变量的boost::shared_ptr

创建现有变量的boost::shared_ptr
EN

Stack Overflow用户
提问于 2011-12-12 02:43:46
回答 4查看 44.6K关注 0票数 30

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

代码语言:javascript
复制
int a = 3;

现在如何创建到aboost::shared_ptr?例如:

代码语言:javascript
复制
boost::shared_ptr< int > a_ptr = &a; // this doesn't work
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-12-12 02:45:46

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

代码语言:javascript
复制
int *a=new int;
boost::shared_ptr<int> a_ptr(a);

也就是说,您肯定不希望将堆栈变量放入shared_ptr中,否则会发生不好的事情

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

代码语言:javascript
复制
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

此外,值得注意的是,如果您能够使用c++11标准,则shared_ptr是在该标准中。你可以像Herb Sutter在build talk中提到的那样,将auto与make_shared结合使用。

代码语言:javascript
复制
#include <memory>

int a=9;
auto a_ptr=std::make_shared(9);
票数 45
EN

Stack Overflow用户

发布于 2011-12-12 05:43:39

首先,你有一个错误,因为shared_ptr不会自动从适当类型的指针转换。你必须明确声明这是你想要做的:

代码语言:javascript
复制
int a = 3;
::boost::shared_ptr< int > a_ptr(&a); // DO NOT DO THIS!

不过,您还有另一个问题。想象一下这段代码的效果:

代码语言:javascript
复制
int a = 3;
delete &a;

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

您有两种方法来处理这个问题。一个是创建一些可以删除的东西,可以删除()。另一种是确保shared_ptr实际上不会删除它所指向的东西。每种方法都有其优点和缺点。

制作可以删除的东西:

优点:

  • 简单易用。
  • 您不必担心对象的生存期。

缺点:

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

具体操作方法:

代码语言:javascript
复制
::boost::shared_ptr<int> a_ptr(::boost::make_shared(a));

这非常类似于(这也会起作用):

代码语言:javascript
复制
::boost::shared_ptr<int> a_ptr(new int(a));

但它的效率要稍微高一些。::boost::make_shared做了一些魔术,在连续内存中分配引用计数和对象,这节省了对分配器的调用,并提高了引用的局部性。

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

优点:

虽然它仍然涉及到引用count

  • Directly的堆分配,但它解决了手头的问题(您所指向的东西不能被引用shared_ptr引用a,所以如果您更改它的值,那么通过指针访问它的东西将看到新值。

缺点:

  • 要求更多地了解shared_ptr的工作原理,这意味着阅读您的代码的人也必须知道。
  • 如果您所指向的东西在所有shared_ptr之前超出了范围,那么这些指针就会变得悬空,这是不好的。
  • 上一点使这是一个非常危险的解决方案<代码>E244。我通常会避免这种情况。<代码>H245<代码>F246

具体操作方法:

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

代码语言:javascript
复制
void do_nothing_deleter(int *)
{
    return;
}

然后在函数中:

代码语言:javascript
复制
int a = 3;
::boost::shared_ptr a_ptr(&a, do_nothing_deleter);
票数 33
EN

Stack Overflow用户

发布于 2011-12-12 02:56:18

您所编写的内容不会起作用,因为您要查找的shared_ptr的构造函数是explicit,因此您需要像这样编写它

代码语言:javascript
复制
boost::shared_ptr<int> a_ptr(&a); // Don't do that!

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

代码语言:javascript
复制
boost::shared_ptr<int> a_ptr(&a, noop_deleter);

针对C++11的noop_deleter实现:

代码语言:javascript
复制
auto noop_deleter = [](int*) {};

C++03版本:

代码语言:javascript
复制
// Can't be put in local scope
struct {
    void
    operator()(int*) const
    {}
} noop_deleter;
票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8466459

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档