我想在需要时推送一系列清理函数。我使用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提前感谢!
发布于 2011-11-08 23:56:09
没有“不使代码复杂化的单行解决方案”。
最糟糕的解决方案是将参数存储在全局变量中,然后在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类型的向量,它在销毁时调用fileWriter::closeAnimation。
发布于 2011-11-09 00:29:38
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 );
}像使用atexit一样使用callAtExit,但它应该适用于任何可以不带参数调用的东西(包括boost::function)。或者,您也可以编写自己的从CallInDestructor派生的类,只要您采取措施确保所有实例都是动态分配的(因为构造函数会注册对象以便将其删除);这些类可以包含您想要的任何附加数据。
发布于 2011-11-08 23:45:27
问题是bind返回一个函数对象,而atexit接受一个指向返回void且不带参数的函数的指针。
您可以尝试这样做:
void fun() {
fileWriter::closeAnimation("0");
}
atexit(fun);https://stackoverflow.com/questions/8053000
复制相似问题