用于记录学习boost::bind() 和boost::function()的知识点。
一.bind和函数的绑定主要是以下几种:
首先定义函数:
void func1()
{
std::cout << " hello bind " << std::endl;
}
void func2(int a,int b,string c)
{
std::cout << " first element is :" << a << std::endl;
std::cout << " second element is :" << b << std::endl;
std::cout << " third element is :" << c << std::endl;
}
class Demo
{
void func1();
void func2(int a,int b,string c);
}
(1).绑定非成员函数:
boost::bind(func1); //传递一个函数名字给bind
boost::bind(&func1); //传递一个函数的地址给bind
以上两种绑定方式都可以,只是绑定函数,但是没有运行函数。
(2).非成员函数传递参数:
boost::bind(func2,_1,_2,_3); //传入参数,_1,_2,_3,是占位符,表示传入的参数
boost::bind(&func2,_1,_2,_3);
通过"下划线+数字" 表示传入第几个参数
(3).绑定类的成员函数:
Demo object;
boost::bind(&Demo::func1,&object); //传入类的实例object
boost::bind(&Demo::func2,&object,_1,_2); //传入类的实例object,_1和_2是占位符,表示传入的两个参数.
以上的boost::bind表示的是对两个类成员函数的绑定,类成员函数的绑定必须要加&符号,并且需要传入该类的实例对象.&object也可以使用ref(object)来传入引用。
(4).绑定模板函数
与其他的函数绑定的方式 基本差不多,主要是在绑定的时候,需要明确的说明下绑定的参数类型,看下面例子:
template<typename T>
void add(T arg1, T arg2)
{
std::cout << arg1 + arg2 << std::endl;
}
boost::bind(add<int>,_1,_2)(3,4); //绑定的时候说明参数类型是int 类型
boost::bind(add<float>,_1,_2)(3.2,4.6); //绑定的时候 说明参数类型是float类型
二.下面看一个简单的例子
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <string>
using namespace std;
class Demo
{
public:
Demo(int i):n(i)
{
};
~Demo()
{
};
public:
template<typename callback>
void Callfunc(callback f) //存储回调函数
{
func_ = f;
}
void run() //用于调用回调函数
{
if(func_) //需要合法性判断
{
func_(n);
}
}
private:
int n;
typedef boost::function<void(int)> func;
func func_;
};
class callback_factory
{
public:
void call_back_func1(int i) //回调函数1
{
cout << "****func1**** :"<< i*3 << endl;
}
void call_back_func2(int i,int j) //回调函数2
{
cout << "****func2***** :" << i*j*3 << endl;
}
};
int main()
{
Demo object(10);
callback_factory callback;
object.Callfunc(boost::bind(&callback_factory::call_back_func1,boost::ref(callback),_1)); //绑定成员函数,需要传入一个实例
object.run();
cout << "---------------" << endl;
object.Callfunc(boost::bind(&callback_factory::call_back_func2,ref(callback),6,_1));
object.run();
return 0;
}
运行的结果如下:
上面的例子中需要注意的一点就是,void run() 函数中需要对func_对象进行判断空操作。function 操作是使用拷贝语义保存参数的,参数较大的时候,拷贝的代价很大,所以使用ref库对callback实例进行传引用。