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; } 
  1. 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;     } }; 
  2. then can write take() function takes ownership of shared_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).

  3. now can manually wrap f(a*) this:

    void f_sp( const boost::shared_ptr<a> & ) {     f( take( ) ); } 
  4. 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

Popular posts from this blog

c# - how to write client side events functions for the combobox items -

exception - Python, pyPdf OCR error: pyPdf.utils.PdfReadError: EOF marker not found -