问题
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