- 1什么是函数对象
- 2Boostbind
- 绑定自由函数
- 绑定全部参数
- 不绑定全部参数
- 绑定类的函数
- boostbind绑定的值是拷贝形式的值传递
- 绑定自由函数
1、什么是函数对象
在了解函数对象之前,应该先知道什么是函数指针,函数指针不再介绍了。函数对象用起来比函数指针更加灵活,且可以实现内联函数。
函数对象是具有函数功能的对象。怎么才能使对象具有函数的功能呢?答案是重载操作符()。加入要实现两个整数相加:
class Add
{
public:
int operator()( int a, int b)
{
return a+b;
}
};
Add add;
add(1,2);
上面就是实现了一个函数对象,在执行add(1, 2)时,实际上是调用了重载操作符()。
在boost/function.cpp中可以创建函数对象。例如
#include<boost/function.hpp>
boost::function<int (int, int) > F;
表示创建了一个函数参数为两个int,返回值为int的函数对象。
如果使用泛型,那么可以实现一个泛型的函数对象
class Add
{
template<typename T>
public:
T operator()( T a, T b)
{
return a+b;
}
};
Add add;
add(1,2);
add(1.1, 2.2);
2、Boost::bind
在知道了函数对象之后,再来看看boost::bind,bind的返回值就是函数对象,之后就可以像调用函数那样来调用函数对象。
bind的用法大概分为两种,一种是绑定自由函数,即不依赖类的函数;二是绑定类函数。在绑定自由函数时使用方法为bind(&函数名, 参数1, 参数2……);在绑定类函数时,使用方法为bind(&类名::方法名, 类实例指针, 参数1, 参数2……)。在绑定的参数中,参数1,参数2这样的参数可以用占位符_1,_2代替,下面举例说明。
绑定自由函数
以加法函数为例
int Add(int a, int b)
{
return a+b;
}
绑定全部参数
boost::bind(&Add, 1, 2)()相当于相当于调用了函数Add(1, 2)。这里boost::bind(&Add, 1, 2)绑定了函数Add,并在绑定时指定了参数,返回函数对象,之后再加上了(),相当于调用了函数对象。
不绑定全部参数
在上面的绑定中,boost::bind(&Add, 1, 2)指定了参数,相当于a=1, b=2。在绑定也可以不绑定参数或只绑定一部分参数。例如
boost::bind(&Add, 1, _1)( 2)
表示在绑定时只指定了一个参数a=1,b的参数使用了占位符_1,在函数对象调用函数时指定占位符的值。
还有其他用法,以例子说明
boost::bind(&Add, _1, _2)( 1, 2)相当于调用了Add(1, 2)
boost::bind(&Add, _2, _1)( 1, 2)相当于调用了Add(2, 1)
boost::bind(&Add, _1, _1)( 2)相当于调用了Add(2, 2)
boost::function
绑定类的函数
对于非静态函数,用法为bind(&类名::方法名, 类实例指针, 参数1, 参数2……)。
例如:
class testBind
{
public:
int Add(int a, int b)
{
return a+b;
}
};
testBind test;
cout<<boost::bind(&testBind::Add, test,1, 2)()<<endl;
cout<<boost::bind(&testBind::Add, &test,1, 2)()<<endl;
cout<<boost::bind(&testBind::Add, _1,1, 2)(test)<<endl;
上面三个调用都相当于调用test.Add(1, 2)。可以看出,test还可以作为参数,用占位符代替。
boost::bind绑定的值是拷贝形式的值传递
boost::bind() 返回的函数对象会保存要绑定的实参,这个实参是值拷贝的形式保存。例如:
void Add(int& a)
{
++a;
}
int n=1;
boost::bind(&Add, n)();
cout<<n<<endl;
运行之后,n仍然为1。要想n为2,则需要返回的函数对象保存的值是引用或指针传递。使用引用值传递,加上boost::ref。
boost::bind(&Add, boost::cref(n))();
绑定到一个对象的成员函数上时,以前面的例子为例:
cout<<boost::bind(&testBind::Add, test,1, 2)()<<endl;
这里拷贝了test对象。
cout<<boost::bind(&testBind::Add, &test,1, 2)()<<endl;
这里没有拷贝,使用引用和指针时不会有拷贝对象的问题。
版权声明:本文为博主原创文章,未经博主允许不得转载。