我可以为局部变量创建boost :: shared_ptr吗?

时间:2013-02-12 10:53:11

标签: c++ boost shared-ptr

我有一些方法可以引用给定的对象,有些方法正在使用boost::shared_ptr。到目前为止,在我的测试方法中,我创建了一个指向其中一个对象的shared_ptr,并将*ptr传递给期望引用的方法。是否可以反过来做,例如在堆栈上创建一个本地对象,然后以安全的方式创建一个指向它的共享指针,以获得传统指针的&obj运算符的直接替代方法?

5 个答案:

答案 0 :(得分:12)

如果您发现需要这个,那么您的代码可能会出现严重错误。

如果函数采用共享指针,那应该是因为它们需要来延长对象的生命周期。如果他们不需要延长对象的生命周期,他们应该参考。

通过你正在做的事情,他们无法延长对象的生命周期。如果他们需要,也不能,他们可能会通过您传递的共享指针的副本来访问超出范围的对象。吊杆。

这可能有点意义。它们可能需要延长寿命,但是您将确保对象保持有效的时间长于它们可能需要延长的最长时间。但我仍强烈建议不要这样做。它非常脆弱,并且使您调用的所有代码完全依赖于调用代码的行为。

答案 1 :(得分:10)

#include <boost/shared_ptr.hpp>

void null_deleter(int *)
{}

int main()
{
    int i = 0;
    boost::shared_ptr<int> p(&i, &null_deleter);
}

答案 2 :(得分:6)

您可以在表单的构造函数中传递适当的删除器:

template<class Y, class D> shared_ptr(Y * p, D d);

删除对象必须在operator()()中不执行任何操作,例如函数:

template <typename T>
void no_op(T*) {}

然后你可以构建:

boost::shared_ptr<Foo> f(&obj, no_op<Foo>);

答案 3 :(得分:0)

您可以使用c ++ 11 lambda函数:

boost::shared_ptr<Foo> f(&obj, \[ ](Foo*){});

答案 4 :(得分:0)

您可以在构造函数中传递null_deleter。

#include <boost/shared_ptr.hpp>
#include <boost/core/null_deleter.hpp>
int main()
{
   int a = 0;
   boost::shared_ptr<int> pi(&a, boost::null_deleter());
}

但请注意这种情况:破坏后使用对象:

#include <boost/shared_ptr.hpp>
#include <boost/core/null_deleter.hpp>


class Y
{
public:
    void  tryUse()
    {
         std::cout << "attempt to use :"<< (uintptr_t)(void*)this<< std::endl;
    }
    ~Y()
    {
         std::cout << "destructor: "<< (uintptr_t)(void*)this<< std::endl;
    }
};

struct Y_user
{
     boost::shared_ptr<Y> p;
    ~Y_user()
    {

        std::cout << "Y_user destructor: "<< (uintptr_t)(void*)this<< std::endl;
        if (p.get())
            p->tryUse();
    }
};

int main()
{
    {
        Y_user yu;
        Y y;
        boost::shared_ptr<Y> p (&y, boost::null_deleter() );
        yu.p = p;
    }
}

将导致控制台输出如下:

destructor: 140737179995232 
Y_user destructor: 140737179995264
attempt to use :140737179995232