function
概念
- function是一个模板类,它就像一个包装了函数指针或函数对象的容器(只有一个元素)。
- 可以把它想象成一个泛化的函数指针,而且他非常适合代替函数指针,存储用于回调的函数。
- 如下定义了一个能够容纳void(int)类型的function对象:
- 使用function需要包含头文件"boost/function.hpp",C++11已经支持function。
function<void(int)> funo;
一些成员函数:
- target():返回对象内部的可调用物Functor的指针,对象为空则返回NULL
- contains():检测是否持有一个Functor。
- clear():将对象清空,与"= 0"效果相同。
- empty():测试对象是否为空,也可以在一个bool上下文中直接测试它是否为空。
- operator==、operator!=:与一个函数或函数对象进行比较。
- operator():调用内部的可调用物,它也会将参数传给可调用物。
使用
int FuncName(int a, int b)
{
return a + b;
}
int main()
{
function<int(int, int)> funo;
funo = FuncName;
if (funo)
{
cout << funo(3, 4) << endl;
}
return 0;
}
回调
void call_back_func(int i)
{
cout << i << endl;
}
class CTestClass
{
public:
CTestClass(int i) :m_iNum(i) {}
public:
template<typename CallBack>
void SetCallBack(CallBack f)
{
m_fFun = f;
}
void run()
{
if(m_fFun)
m_fFun(m_iNum);
}
private:
function<void(int)> m_fFun;
int m_iNum;
};
int main()
{
CTestClass dc(10);
dc.SetCallBack(call_back_func);
dc.run();
return 0;
}
存储Lambda表达式
int main()
{
//存储Lambda,捕获变量num
int num = 100;
std::function<void()> f = [num] {
cout << "num:" << num << endl;
};
f();
getchar();
return 0;
}
存储类的成员函数
C++中A类对象里调用B类对象的成员函数一般使用以下三种方法:
- 使用虚函数:在A类中保存B类对象的基类指针m_ptr,在B类中重写基类的虚函数,通过B类的基类指针m_ptr来调用B类的虚函数。
- 使用function + bind:在A类中保存B类对象的成员函数的function(通过bind),通过function来调用B类的成员函数。
- 使用function + lambda:在A类中保存B类对象的成员函数的function(通过捕获this指针的lambda),通过function来调用B类的成员函数。
#include "boost/bind.hpp"
class CCall_back_factory
{
public:
void call_back_fun_1(int i)
{
cout << i * 2 << endl;
}
void call_bcak_fun_2(int i, int j)
{
cout << i * j * 2 << endl;
}
};
class CTestClass
{
public:
CTestClass(int i) :m_iNum(i) {}
public:
template<typename CallBack>
void SetCallBack(CallBack f)
{
m_fFun = f;
}
void run()
{
if(m_fFun)
m_fFun(m_iNum);
}
private:
function<void(int)> m_fFun;
int m_iNum;
};
int main()
{
CTestClass dc(10);
CCall_back_factory cbf;
dc.SetCallBack(bind(&CCall_back_factory::call_back_fun_1, cbf, _1));
dc.run();
int j = 5;
dc.SetCallBack(bind(&CCall_back_factory::call_bcak_fun_2, cbf, _1, j));
dc.run();
return 0;
}