Can I create a boost::shared_ptr to a local variable?

余生长醉 提交于 2019-12-23 10:08:56

问题


I have some methods that take a reference to a given object, and some are taking boost::shared_ptr. So far in my test method I created a shared_ptr pointing to one of these objects and pass *ptr to the methods expecting a reference. Is it possible to do it the other way round, e.g. create a local object on the stack, and then create a shared pointer to it in a safe way, to arrive at the straightforward alternative to &obj operator with traditional pointers?


回答1:


#include <boost/shared_ptr.hpp>

void null_deleter(int *)
{}

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



回答2:


If you find you need this, something is probably horribly wrong with your code.

If the functions take a shared pointer, it should be because they need to extend the lifetime of the object. If they don't need to extend the lifetime of the object, they should take a reference.

With what you're doing, they can't extend the lifetime of the object. If they need to, and can't, they may wind up accessing an object that has gone out of scope through a copy of the shared pointer you passed them. Boom.

It's slightly possible this might make sense. It may be that they need to extend the lifespan but you will make sure that the object remains valid longer than the longest they might possibly need to extend it. But I'd still strongly suggest not doing this. It's incredibly fragile and makes all the code you call dependent on exactly how the calling code behaves.




回答3:


You can pass an appropriate deleter in the constructor of the form:

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

The deleter object must do nothing in its operator()(), such as the function:

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

with which you can then construct:

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



回答4:


You can use c++11 lambda function:

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



回答5:


You can pass null_deleter in the constructor.

#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());
}

But watch this case: using object after destruction:

#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;
    }
}

Will lead to console output like this:

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


来源:https://stackoverflow.com/questions/14830837/can-i-create-a-boostshared-ptr-to-a-local-variable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!