c++ - Delete raw pointer argument to boost::bind -
lets have heap allocated a*
, want pass argument boost::bind
. boost::bind
saved later processing in stl container of boost::functions
's.
i want ensure a*
destroyed @ destruction of stl container.
to demostrate:
a* pa = new a(); // time later container.push_back(boost::bind(&someclass::handlea, this, pa); // time later container destroyed => pa destroyed
how can done?
edit
maybe want not realistic.
i have raw pointer , function receives raw pointer. call delayed means of boost::bind. @ point want automatic memory management in case boost::bind want executed. i'm lazy, want use "ready" smart-pointer solution.
std::auto_ptr looks candidate, ...
auto_ptr<a> pautoa(pa); container.push_back(boost::bind(&someclass::handlea, this, pautoa);
doesn't compile (see here)
auto_ptr<a> pautoa(pa); container.push_back(boost::bind(&someclass::handlea, this, boost::ref(pautoa));
pautoa destroyed, deleting underlying pa.
edit 02
in mentioned container need store misc "callbacks" different arguments. of them raw pointers object. since code old, not can change it.
writing own wrapper storing callbacks in container last resort (while maybe one), hence bounty.
the idea of @pmjordan going in right direction. replied can't use shared_ptr
, because can't take ownership once constructed. not entirely correct: shared_ptr
's custom deleter mechanism, can. how:
assume these toy defintions a
, f(a*)
:
struct { ~a() { std::cout << "~a()" << std::endl; } }; void f( * ) { std::cout << "in f(a*)" << std::endl; delete a; }
write deleter can "switched off":
struct opt_delete { bool m_delete; opt_delete() : m_delete( true ) {} template <typename t> void operator()( t * t ) { if ( m_delete ) delete t; } };
then can write
take()
function takes ownership ofshared_ptr
payload again:template <typename t> t * take( const boost::shared_ptr<t> & sp ) { opt_delete * d = boost::get_deleter<opt_delete>( sp ); assert( d ); assert( d->m_delete == true ); d->m_delete = false; return sp.get(); }
(this leave payload in remaining
shared_ptr
instances, case, that's ok, ,assert()
s cover cases when it's not).now can manually wrap
f(a*)
this:void f_sp( const boost::shared_ptr<a> & ) { f( take( ) ); }
and finally, test 2 scenarios:
int main( int argc, char * argv[] ) { const boost::shared_ptr<a> a( new a, opt_delete() ); const boost::function<void()> func = boost::bind( &f_sp, ); if ( argc >= 2 && *argv[1] == '1' ) // call 'func' func(); else ; // don't return 0; }
executing test program 1
argument print
in f(a*)
~a()
and without (or other argument), print
~a()
you can extend test harness put func
container first, it'll still safe. thing isn't safe in case calling func
copies more once (but you'll trigger second assertion in take()
).
edit: note mechanism isn't thread-safe. make thread-safe, need supply opt_delete
mutex synchronise operator()
take()
.
Comments
Post a Comment