7

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

4

5 回答 5

15

如果你发现你需要这个,那么你的代码可能存在严重错误。

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

通过您正在做的事情,他们无法延长对象的生命周期。如果他们需要并且不能,他们可能最终会通过您传递给他们的共享指针的副本访问超出范围的对象。繁荣。

这有点可能是有道理的。他们可能需要延长使用寿命,但您将确保对象保持有效的时间超过他们可能需要延长它的最长期限。但我仍然强烈建议不要这样做。它非常脆弱,使您调用的所有代码都完全依赖于调用代码的行为方式。

于 2013-02-12T11:03:10.200 回答
10
#include <boost/shared_ptr.hpp>

void null_deleter(int *)
{}

int main()
{
    int i = 0;
    boost::shared_ptr<int> p(&i, &null_deleter);
}
于 2013-02-12T10:57:02.340 回答
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>);
于 2013-02-12T10:57:17.267 回答
0

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

boost::shared_ptr<Foo> f(&obj, \[ ](Foo*){});
于 2015-04-24T07:48:39.103 回答
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
于 2017-02-02T22:41:55.927 回答