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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8466459/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:37:19  来源:igfitidea点击:

Create a boost::shared_ptr to an existing variable

c++boostshared-ptrsmart-pointers

提问by Bill Cheatham

I have an existing variable, e.g.

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

int a = 3;

How can I now create a boost::shared_ptrto a? For example:

我现在如何创建一个boost::shared_ptrto a?例如:

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

回答by 111111

although you should put the variable into a managed pointer on it's creation to do it from an existing pointer.

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

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

That said you most definitely do not want to be putting stack variables into shared_ptr BAD THINGS WILL HAPPEN

也就是说你绝对不想将堆栈变量放入 shared_ptr 坏事会发生

If for some reason a function takes shared_ptr and you only have a stack varaible you are better off doing this:

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

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

See here:

看这里:

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

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

also it is worth noting that shared_ptr is in the c++11 standard if you are able using that. You can use auto in combination with make_shared like Herb Sutter notes in the build talk.

还值得注意的是,如果您能够使用 shared_ptr,则它在 c++11 标准中。您可以像构建谈话中的 Herb Sutter 笔记一样将 auto 与 make_shared 结合使用。

#include <memory>

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

回答by Omnifarious

First, you have an error because shared_ptr's will not automatically convert from a pointer of the appropriate type. You have to explicitly state that's what you want to do:

首先,您有一个错误,因为shared_ptr's 不会从适当类型的指针自动转换。您必须明确说明这就是您要执行的操作:

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

You have another problem though. Imagine the effect of this code:

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

int a = 3;
delete &a;

In the first example I gave, this will inevitably happen, even if it's not quite so direct. shared_ptr's whole reason for existence is deleting things when all the pointers to it go away. This, of course, will cause all manner of strange behavior.

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

You have two ways of dealing with this issue. One is to create something that canbe deleted. The other is to make sure that shared_ptrdoesn't actually delete the thing it points to. There are pros and cons to each.

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

Making something that can be deleted:

制作可以删除的东西:

Pros:

优点:

  • Simple and easy.
  • You don't have to worry about object lifetimes.
  • 简单易行。
  • 您不必担心对象的生命周期。

Cons:

缺点:

  • A bit on the slow side, since it will involve a heap allocation or two.
  • The resulting shared_ptrwill refer to a copy, so modifications to awill not be reflected in the value of the thing it points to.
  • 有点慢,因为它会涉及一两个堆分配。
  • 结果shared_ptr将引用一个副本,因此a对它的修改不会反映在它指向的事物的值中。

How to do it:

怎么做:

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

This is rather similar to (and this will also work):

这与(这也将起作用)非常相似:

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

But it's slightly more efficient. ::boost::make_shareddoes some magic to allocate the reference count and the object in contiguous memory which saves on calls to the allocator and improves locality of reference.

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

Making it so that shared_ptrdoesn't actually delete what it points to:

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

Pros:

优点:

  • Faster, though it still involves a heap allocation for the reference count
  • Directly addresses the issue at hand (the thing you're pointing to can't be deleted).
  • The shared_ptrrefers to a, so if you change its value things that access it through the pointer will see the new value.
  • 更快,尽管它仍然涉及引用计数的堆分配
  • 直接解决手头的问题(您指向的东西无法删除)。
  • shared_ptra,所以如果你改变它的价值的东西,它的访问通过指针将看到新的价值。

Cons:

缺点:

  • Requires knowing a bit more about how shared_ptrworks, which means the people reading your code have to know too.
  • If the thing you're pointing to goes out of scope before all shared_ptr's that point to it do, then those pointers become dangling, and that's bad.
  • The previous point makes this a very risky solution. I would generally avoid it.
  • 需要更多地了解如何shared_ptr工作,这意味着阅读您的代码的人也必须知道。
  • 如果你指向的东西在所有shared_ptr指向它的东西之前就超出了范围,那么这些指针就会变得悬空,这很糟糕。
  • 前一点使得这是一个非常危险的解决方案。我通常会避免它。

How to do it:

怎么做:

Somewhere outside the function (probably in an anonymous namespace):

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

void do_nothing_deleter(int *)
{
    return;
}

And then in the function:

然后在函数中:

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

回答by Luc Danton

What you wrote won't work because the constructor of shared_ptryou're looking for is explicit, so you'd need to write it like so

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

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

The problem with thathowever, is that deletewill be called on the stored value of a_ptr. Since in your example ahas automatic storage duration, this is very bad. So we pass in a custom deleter too:

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

boost::shared_ptr<int> a_ptr(&a, noop_deleter);

An implementation of noop_deleterfor C++11:

的实现noop_deleter为C ++ 11:

auto noop_deleter = [](int*) {};

C++03 version:

C++03版本:

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

回答by Lalaland

You cannot create a boost::shared_ptr for an existing variable. Items stored in a boost::shared_ptr are stored at creation.

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

You can however make a boost::shared_ptr that is a copy of an existing variable.

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

For example

例如

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

Note that you will need to include <boost/make_shared.hpp>for make_shared.

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