c – 删除boost :: bind的原始指针参数
假设我有堆分配A *,我想将其作为参数传递给boost :: bind.
保存boost :: bind以便稍后在某些STL中处理,比如boost :: functions的容器. 我想确保在销毁STL容器时销毁A *. 示范: A* pA = new A(); // some time later container.push_back(boost::bind(&SomeClass::HandleA,this,pA); // some time later container is destroyed => pA is destroyed too 怎么做到呢? 编辑 也许我想要的不是那么现实. 我有原始指针和函数接收原始指针.通过boost :: bind延迟调用.此时我想要自动内存管理,以防boost :: bind想要执行.我很懒,所以我想使用“准备好”的智能指针解决方案. std :: auto_ptr看起来像个好人,但是…… auto_ptr<A> pAutoA(pA); container.push_back(boost::bind(&SomeClass::HandleA,pAutoA); 不编译(见here) auto_ptr<A> pAutoA(pA); container.push_back(boost::bind(&SomeClass::HandleA,boost::ref(pAutoA)); pAutoA被破坏,删除了底层的pA. 编辑02 在上面提到的容器中,我将需要使用不同的参数存储misc“回调”.其中一些是对象的原始指针.由于代码是旧的,我并不总是可以改变它. 编写自己的包装器来存储容器中的回调是最后的手段(可能是唯一的),因此是赏金. 解决方法
@pmjordan的想法已经朝着正确的方向发展.您回复说您不能使用shared_ptr,因为一旦构造,您就无法取回所有权.但这并不完全正确:使用shared_ptr的自定义删除机制,您可以.这是如何:
假设你的A和f(A *)的这些玩具定义: struct A { ~A() { std::cout << "~A()" << std::endl; } }; void f( A * a ) { std::cout << "in f(A*)" << std::endl; delete a; } >写一个可以“关闭”的删除器: struct opt_delete { bool m_delete; opt_delete() : m_delete( true ) {} template <typename T> void operator()( T * t ) { if ( m_delete ) delete t; } }; >然后你可以编写一个take()函数,它再次获得shared_ptr有效负载的所有权: 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(); } (这会将有效负载留在剩余的shared_ptr实例中,但对于您的情况,这没关系,并且assert()覆盖了不支持的情况). void f_sp( const boost::shared_ptr<A> & a ) { f( take( a ) ); } >最后,测试两种情况: 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,a ); if ( argc >= 2 && *argv[1] == '1' ) // call 'func' func(); else ; // don't return 0; } 将打印执行带有1参数的测试程序
如果没有(或任何其他参数),它将打印出来
您可以扩展测试工具以首先将func放入容器中,但它仍然是安全的.在这种情况下唯一不安全的是多次调用func副本(但是你会在take()中触发第二个断言). 编辑:请注意,此机制不是线程安全的.要使其成为线程安全的,您需要为opt_delete提供一个互斥锁,以使operator()与take()同步. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |