为此得到一个boost :: shared_ptr

时间:2020-03-06 14:48:47  来源:igfitidea点击:

我在我的代码中广泛使用boost:shared_ptr。实际上,分配在堆上的大多数对象都由一个shared_ptr持有。不幸的是,这意味着我不能将this传递给任何需要shared_ptr的函数。考虑以下代码:

void bar(boost::shared_ptr<Foo> pFoo)
{
    ...
}

void Foo::someFunction()
{
    bar(this);
}

这里有两个问题。首先,这不会编译,因为shared_ptr的T *构造函数是显式的。其次,如果我强迫它使用bar(boost :: shared_ptr &lt;Foo>(this))构建,我将创建第二个指向我对象的共享指针,该指针最终将导致两次删除。

这使我想到了一个问题:是否存在任何标准模式来从这些对象之一的方法内部获取我们知道的现有共享指针的副本?使用介入式引用在这里算是我唯一的选择吗?

解决方案

boost有针对该用例的解决方案,请检查enable_shared_from_this

我们可以从enable_shared_from_this派生,然后可以使用" shared_from_this()"而不是" this"生成指向我们自己的自身对象的共享指针。

链接中的示例:

#include <boost/enable_shared_from_this.hpp>

class Y: public boost::enable_shared_from_this<Y>
{
public:

    shared_ptr<Y> f()
    {
        return shared_from_this();
    }
}

int main()
{
    shared_ptr<Y> p(new Y);
    shared_ptr<Y> q = p->f();
    assert(p == q);
    assert(!(p < q || q < p)); // p and q must share ownership
}

当从成员函数中生成线程以将boost :: bind替换为shared_from_this()时,这是一个好主意。这将确保不释放对象。

我们是否真的在bar内制作了更多的pFoo共享副本?如果我们没有在内部做任何疯狂的事情,请执行以下操作:

void bar(Foo &foo)
{
    // ...
}

接受指针的函数想要执行以下两种行为之一:

  • 拥有要传入的对象,并在超出范围时将其删除。在这种情况下,我们可以只接受X *并立即将scoped_ptr包装在该对象周围(在函数主体中)。这将接受" this"或者通常是任何堆分配的对象。
  • 共享指向传入对象的指针(不拥有它)。在这种情况下,我们根本不需要使用scoped_ptr,因为我们不想在函数末尾删除该对象。在这种情况下,理论上我们需要的是shared_ptr(我在其他地方已经看到它称为linked_ptr)。 boost库具有shared_ptr的版本,Scott Meyers的Effective C ++手册(第3版的第18条)中也建议使用此库。

编辑:糟糕,我稍微误解了该问题,现在我看到此答案不能完全解决该问题。无论如何,我都会把它保留下来,以防这对从事类似代码工作的人有所帮助。

只需对函数参数使用原始指针,而不要使用shared_ptr。智能指针的目的是控制对象的生存期,但是对象生存期已由C ++作用域规则保证:它的存在至少与函数结束时一样长。也就是说,调用代码可能无法在函数返回之前删除该对象。因此,只要我们不尝试删除函数内部的对象,就可以确保"哑"指针的安全性。

唯一需要将shared_ptr传递给函数的时间是,当我们要将对象的所有权传递给该函数或者希望该函数复制指针时。