Is there a stock no-op deallocator in Boost to use with boost::shared_ptr
for static objects, etc.
I know it's ultra-trivial to write, but I don't want to sprinkle my code with extra tiny functions if there is already one avai开发者_StackOverflow社区lable.
Yes there is one here:
#include <boost/serialization/shared_ptr.hpp> // for null_deleter
class Foo
{
int x;
};
Foo foo;
boost::shared_ptr< Foo > sharedfoo( &foo, boost::serialization::null_deleter() );
There is, of course, a danger with the fact that you need to know the function you call doesn't store the shared_ptr for later use, as it actually goes against the policy of shared_ptr in that the underlying object remains valid until that of the last instance of the shared_ptr.
Solution uses Boost.Lambda:
#include <boost/shared_ptr.hpp>
#include <boost/lambda/lambda.hpp>
int main()
{
int *p = new int(5);
{
boost::shared_ptr<int> sp(p, boost::lambda::_1);
}
delete p;
}
'boost::lambda::_1' creates an empty functor that takes one argument.
You'll probably want to put a //comment in there to let people know why you did it, though.
- If Boost
<=
1.54, useboost/log/utility/empty_deleter.hpp
. - If Boost
==
1.55, useboost/utility/empty_deleter.hpp
. - If Boost
>=
1.56, useboost/core/null_deleter.hpp
.
Wouldn't it be cleaner just to take an extra reference so the deallocator is never called? (Although that's still not very clean.)
I can't say that there's no function in Boost which would do the job, but it doesn't sound like something they would want to include.
EDIT: Having read the comments and a little documentation, it boils down to this:
Reference leaking. At some point, execute this:
new shared_ptr( my_global_shared_ptr );
Advantages: conceptually easy. Disadvantages: you are leaking something on the heap.
Custom deallocator. Since
shared_ptr
requires little of the deallocator function, an anonymous identity function like that provided in the other answer would do fine.Advantages: leverages Boost and has absolutely no overhead. Disdvantages: requires a little documentation.
Non-static global object. If there is a global
shared_ptr
for your object, that should be the only means of access to it. Replace the declaration of the global with ashared_ptr
intialized bynew my_class
. I think this is best.
There's a ticket for this on the Boost bug tracker: https://svn.boost.org/trac/boost/ticket/1913 - no activity for a long time until some murmur two weeks ago.
FWIW, this what I'm using. I use it in unit tests to adapt a local into a shared_ptr.
// The class NoOp_sptr_Deleter can be used to construct a shared_ptr<>()
// that will NOT delete the pointee.
// This can be helpful in unit-testing. Wrapping a local as a shared_ptr.
// Do take care with the lifetimes though.
struct NoOp_sptr_Deleter
{
void operator()(void const *) const {}
};
template<typename T>
boost::shared_ptr<T> FakeSharedPtrFromRef(T& aRef)
{
return boost::shared_ptr<T>(&aRef, NoOp_sptr_Deleter() );
}
精彩评论