创建一个 boost::shared_ptr 到现有变量

发布于 2024-12-21 03:41:23 字数 219 浏览 4 评论 0原文

我有一个现有变量,例如

int a = 3;

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

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

I have an existing variable, e.g.

int a = 3;

How can I now create a boost::shared_ptr to a? For example:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

暮色兮凉城 2024-12-28 03:41:23

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

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);

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

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

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

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.

#include <memory>

int a=9;
auto a_ptr=std::make_shared(9);
转身泪倾城 2024-12-28 03:41:23

首先,您会遇到错误,因为 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);

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:

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.

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

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_ptr will refer to a copy, so modifications to a will not be reflected in the value of the thing it points to.

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_shared does 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.

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

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_ptr refers to a, so if you change its value things that access it through the pointer will see the new value.

Cons:

  • Requires knowing a bit more about how shared_ptr works, 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.

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);
递刀给你 2024-12-28 03:41:23

您编写的内容将不起作用,因为您正在寻找的 shared_ptr 的构造函数是显式,因此您需要像这样编写它

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 实现:

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

C++11: C++03 版本

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

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

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

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

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

An implementation of noop_deleter for C++11:

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

C++03 version:

// Can't be put in local scope
struct {
    void
    operator()(int*) const
    {}
} noop_deleter;
有木有妳兜一样 2024-12-28 03:41:23

您无法为现有变量创建 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 包含

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文