这两天用c++函数对象。老规矩,好记性不如烂笔头,自己记录一下
1. c++普通函数
int my(int a,int b)
{
return a + b;
}
function<int(int,int)> myFun = my;
int ret = myFun(3,5);//这里ret就是8了
2. extern "c" 函数
extern "C"
{
int my(int a, int b)
{
return a+b;
}
}
function<int(int,int)> myFun = my;
int ret = myFun(3,5);//这里ret就是8了
3. 类成员函数
class test
{
private:
int baseVal;
public:
int my(int a)
{
int ret = a + baseVal;
return ret;
}
test(int val):baseVal(val)
{
}
};
test obj(100);
function<int(int)> func = std::bind(&test::my,&obj,std::placeholders::_1);
int ret = func(5);
cout<<ret<<endl;
4. 回调函数
我个人理解,这个是函数对象的主战场。
比如下面的类:
class test
{
private:
int baseVal;
function<void(void*)> _callback;
public:
int total;
public:
int my(int a)
{
int ret = a + baseVal;
total = ret;
if(ret>10)
{
_callback(this);//触发回调
}
return ret;
}
test(int val):baseVal(val),total(val)
{
}
void set(function<void(void*)> callBackFunc)
{
_callback = callBackFunc;//设置回调函数
}
};
我们可以设置的回调函数,可以是普通的函数,比如lamda函数:
test obj(5);
auto l1 = [](void* para){
test* obj = reinterpret_cast<test*>(para);
cout<<"lamda callback called,total is "<<obj->total<<endl;
};
obj.set(l1);
obj.my(6);//此时回到函数被触发,也就是lamda函数l1被触发
回调函数也可以是我们实际设计的一个类的成员函数,比如:
class box
{
private:
int id;
string ip;
int load;
public:
box(const string& ip,const int id)
{
this->id = id;
this->ip = ip;
load = 0;
}
void callback1(void * para)
{
test* obj = reinterpret_cast<test*>(para);
cout<<"box's call back1 is called,total is "<<obj->total<<endl;
}
};
比如将box类中的callback1注册到test类中:
test obj(5);
box myBox("192.168.1.100",123456);
auto f2 = std::bind(&box::callback1,&myBox,std::placeholders::_1);
obj.set(f2);
obj.my(12);//这里box中的callback1被触发。
并且这里,通过bind,实际上box中的callback1的形参可以不局限于(void* para)。因此,通过函数对象,以及bind,回调函数可以变得更灵活
5. 函数指针
以dll库中的extern "c" 函数为例
typedef int (*P_MY_ADD)(int,int);
function<int(int,int)> gFun;
int main()
{
void* libHandle = dlopen("libmy.so", RTLD_GLOBAL | RTLD_NOW);
P_MY_ADD funcPtr;
funcPtr = (P_MY_ADD)dlsym(libHandle,"myAdd");
int ret = funcPtr(5,6);
cout<<ret<<endl;
gFun = funcPtr;
ret=gFun(11,12);
cout<<ret<<endl;
return 0;
}