将值传递给atexit
Passing values to atexit
我想在需要时推送一系列清理函数。我使用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
提前感谢!
如果不使代码复杂化,就没有" 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 fn");
static AtExitAnimationCloser s0 ("0"); // registers closeAnimation("0") at exit
static AtExitAnimationCloser s1 ("1"); // registers closeAnimation("1") at exit
printf("leaving fn");
}
示范: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
的向量,在销毁~T
时调用fileWriter::closeAnimation
。
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
派生,如只要采取措施确保所有实例都是动态的已分配(因为构造函数注册了对象,所以它将被分配)删除);这些类可以包含您想要的任何其他数据。
问题是bind返回一个函数对象,而atexit接受一个指向一个返回void且不带形参的函数的指针。
你可以试试:
void fun() {
fileWriter::closeAnimation("0");
}
atexit(fun);
- 为什么可以将左值传递给"std::async",即使它引用了右值
- 当值传递给C++中的运算符重载函数时会发生什么
- 如何将非可变参数值传递给 fmt::format?
- 将 qml 项目值传递给 cpp 后如何与它们进行交互?
- NDK:将文本字段值传递给 c++ 字符串
- 如何将值传递给 lambda 函数
- 如何在C++中将std::string值传递给RegSetValueEx()
- 如何将 c ++ 变量的值传递给 hadoop HDFS 的 bash 系统命令?
- C++ 通过参数将值传递给 char 数组
- 如何将值传递给MFC消息映射函数on_command
- 使用JNI将长值传递给Java
- 如何在不使用 Argv 和 Argc 的情况下将 Sum 值传递给 C++ 程序
- C++ 将值传递给 fStream
- 如何将函数中的多个值传递给C++中的不同函数
- 将多个解析值传递给 addPositionalArgument 函数
- C++为什么将左值传递给move构造函数对模板有效
- 一种自动检测对象的方法,该方法通过值传递给c++中的函数
- 将值传递给main(int,char**)
- 将大于long类型的最大值的值传递给C中的fseek
- 将值传递给atexit