您的位置:首页 > 其它

Boost::bind学习

2015-07-22 21:47 232 查看
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;


这里没有拷贝,使用引用和指针时不会有拷贝对象的问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: