class test{
public :
void * func(void *){
std::cerr << " void * func(void *) output" << std::endl;
return nullptr;
}
};
typedef void* (test::* MFP)(void*);
//example code:
test *tt = new test();
MFP p = &test::func;
//进行第一次转换
void * pfunc=(unsigned*)&p;
//根据传值获取成员函数地址
MFP * addr =(MFP*)pfunc;
//绑定函数与类
auto scall = std::bind(*addr,*tt,std::placeholders::_1);
//执行操作
void* px = NULL;
scall(px);
在C++11甚至C++20都开始盛行的年代std::function(通用多态函数封装器)大行其道,为什么还要将类的指针函数变型为std::function?
1.为了保持旧代码与新标准的兼容性
2.构建更加灵活而又标准的C++代码
3.便于写一些通用框架或者插件库
下面是测试类test,拥有方法func
class test{
public :
void * func(void *){
std::cerr << " void * func(void *) output" << std::endl;
return nullptr;
}
}
通常,我们会对所有继承test类执行如下定义,也就是说
//执行定义
typedef void* (test::* MFP)(void*)
//将func方法作为参数传递给MFP
//example code:
test *t_ptr = new test();
MFP p = &test::func;
然后就可以采用p(void*)的形式去调用test类的func方法了。美中不足的是,如果所有需要去按照test的模式都需要去继承test类,这尽管保证了继承类的类型安全,却也对C++的使用形成了限制,特别是在与新标准std::function兼容上产生一定“误区”
对于不同的类,包含同样的void * _f(void *)形式的函数如果既不是同一个类,也不想使用重复的包裹代码去包裹函数,可以采取以下的方式将函数地址作为参数传递给bind
//进行第一次转换
void * pfunc=(unsigned*)&p;
//根据传值获取成员函数地址
MFP * addr =(MFP*)pfunc;
//绑定函数与类
auto scall = std::bind(*addr,*t_ptr,std::placeholders::_1);
//执行操作
void* px = NULL;//此处为参数
scall(px);//此处为绑定的test类的func方法
参照上述代码即可实现成员类函数与成员类完全由指针代替,既保留了指针的灵活性,同时又确保了调用函数的类型安全。