我想在需要时推出一系列清理功能。我使用atexit为一个没有任何参数的清理函数执行此操作,但我不确定如何将此方法扩展到多个清理功能。我对boost :: bind不是很熟悉,但是假设这是一个好主意,因为我将我的函数绑定到线程...
在c ++中,我试图让以下内容起作用:
功能定义
static void closeAnimation(string prefix="");// static member of fileWriter
代码:
atexit(boost::bind(fileWriter::closeAnimation, "0")); // I want to first prefix to be "0"
错误:
cannot convert ‘boost::_bi::bind_t<void, void (*)(std::basic_string<char>), boost::_bi::list1<boost::_bi::value<const char*> > >’ to ‘void (*)()’ for argument
提前致谢!
答案 0 :(得分:3)
atexit
是一个遗留的C函数,并不是很适合C ++。您可以
使用atexit
注册多个函数,但所有函数都必须
void (*)()
,没有boost::function
,没有参数。
在C ++中,大多数(如果不是全部)atexit
的功能都被包含在内
由静态对象的析构函数。在你的情况下,我会写点什么
像:
#include <vector>
class CallInDestructor
{
class Registry
{
std::vector<CallInDestructor*> myInstances;
public:
register_caller(CallInDestructor* caller)
{
myInstances.push_back(caller);
}
~Registry()
{
while ( !myInstances.empty() ) {
delete myInstances.back();
myInstances.pop_back();
}
}
};
static Registry& registry()
{
static Registry theOneAndOnly;
return theOneAndOnly;
}
protected:
CallInDestructor() { registry().register_caller( this ); }
public:
virtual ~CallInDestructor() {}
};
template<typename Fnc> void callAtExit( Fnc fnc );
template<typename Fnc>
class ConcreteCallInDestructor : public CallInDestructor
{
Fnc myFnc;
ConcreteCallInDestructor( Fnc fnc = Fnc() ) : myFnc( fnc ) {}
virtual ~ConcreteCallInDestructor() { myFnc(); }
friend void callAtExit<Fnc>( Fnc fnc );
};
template<typename Fnc>
void
callAtExit( Fnc fnc )
{
new ConcreteCallInDestructor<Fnc>( fnc );
}
像callAtExit
一样使用atexit
,但它应该适用于任何事情
可以不带参数调用(包括boost::function
)。
或者您可以编写自己的类,派生自CallInDestructor
,as
只要您采取措施确保所有实例都是动态的
已分配(因为构造函数注册了对象以便它
删除);这些类可以包含您想要的任何其他数据。
答案 1 :(得分:2)
没有“1行解决方案而不会使代码复杂化”。
最糟糕的解决方案是将该参数存储在全局变量中,并在atexit处理程序中检索它
由于您使用的是C ++,静态变量的析构函数也可以用作atexit
处理程序。然后,您可以在该静态变量的构造函数中传递参数以进行参数化,例如
struct AtExitAnimationCloser
{
const char* _which_param;
AtExitAnimationCloser(const char* which_param) : _which_param(which_param) {}
~AtExitAnimationCloser() { FileWriter::closeAnimation(_which_param); }
};
void f()
{
printf("entering f\n");
static AtExitAnimationCloser s0 ("0"); // registers closeAnimation("0") at exit
static AtExitAnimationCloser s1 ("1"); // registers closeAnimation("0") at exit
printf("leaving f\n");
}
示范:http://www.ideone.com/bfYnY
请注意,静态变量与其名称绑定,因此您不能说
for (it = vecs.begin(); it != vecs.end(); ++ it)
{
static AtExitAnimationCloser s (*it);
}
为所有内容调用atexit。但是你可以让静态变量本身占据整个范围
static AnotherAtExitAnimationCloser s (vecs.begin(), vecs.end())
最后,使用惯用的C ++我不认为你需要使用这些技巧......你可以存储一个类型为T的向量,它在destroy~T调用fileWriter::closeAnimation
上。
答案 2 :(得分:-1)
问题是bind返回一个函数对象,atexit接受一个指向函数的指针,该函数返回void并且没有参数。
你可以试试这个:
void fun() {
fileWriter::closeAnimation("0");
}
atexit(fun);