Boost::bind学习

  • 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;

这里没有拷贝,使用引用和指针时不会有拷贝对象的问题。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 22:53:10

Boost::bind学习的相关文章

boost库学习随记六:使用同步定时器、异步定时器、bind、成员函数回调处理、多线程的同步处理示例等

一.使用同步定时器 这个示例程序通过展示如何在一个定时器执行一个阻塞等待. [cpp] view plaincopy //makefile #---------------------------------------------------------- #makefile helloworld测试用例 # # # # #----------------------------------------------------------- ggg=g++ exe=asiotimer #所有的

boost asio 学习(六) 定时器

http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting- started-with-boostasio?pg=7 6 定时器 boost::asio 提供了一个 deadline_timer class来提供同步与异步的接口. BOOST文档提供了一组优秀示例.第一个例子,将创建一个间隔5秒的定时器. #include <boost/asio.hpp> #include <boost/shared_ptr.hpp&

Boost Thread学习笔记

thread自然是boost::thread库的主 角,但thread类的实现总体上是比较简单的,前面已经说过,thread只是一个跨平台的线程封装库,其中按照所使用的编译选项的不同,分别决定使用 Windows线程API还是pthread,或者Macintosh Carbon平台的thread实现.以下只讨论Windows,即使用 BOOST_HAS_WINTHREADS的情况.thread类提供了两种构造函数:thread::thread()thread::thread(const func

Boost Thread学习笔记五

多线程编程中还有一个重要的概念:Thread Local Store(TLS,线程局部存储),在boost中,TLS也被称作TSS,Thread Specific Storage.boost::thread库为我们提供了一个接口简单的TLS的面向对象的封装,以下是tss类的接口定义: class tss{public:    tss(boost::function1<void, void*>* pcleanup);    void* get() const;    void set(void*

boost asio 学习(九) boost::asio 网络封装

http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting- started-with-boostasio?pg=10 9. A boost::asio network wrapper (TCP) 现在我们了解asio和TCP网络方面的知识,我们可以尝试下封装网络底层.通过使用这个封装,我们可以重用代码并且将精力集中于业务逻 辑方面而不在网络通讯方面花费太多精力. 重要提示:本代码仅仅用于教学目的.不要在商业系统中使用该代码,

boost asio 学习(七) 网络基础 连接器和接收器(TCP示例)

http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting- started-with-boostasio?pg=8 7. Networking basics: connectors and acceptors (TCP)我们来学习boost的TCP网络编程.之前的篇章已经介绍了网络系统框架.我们只需要学习网络API函数即可 我们首先学习如何同步的连接主机.我们的代码作为客户端运行,使用tcp::socket对象.tcp::s

Boost::Bind 基础

先了解一下:函数对象 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象.[1] 一个类对象,表现出一个函数的特征,就是通过"对象名+(参数列表)"的方式使用一个 类对象,如果没有上下文,完全可以把它看作一个函数对待.这是通过重载类的 operator()来实现的.比如,对于调用 int s = sum(1, 1); 你可能把它看作一个函数调用: int sum(int i, int j) { return i+j; } 但很可能

c++ boost库学习三:实用工具

noncopyable 大家都知道定义一个空类的时候,它实际包含了构造函数,拷贝构造函数,赋值操作符和析构函数等. 这样就很容易产生一个问题,就是当用户调用A a(“^_^") 或者A c="^_^" 时会发生一些意想不到的行为,所以很多时候我们需要禁用这样的用法. 一种方法就是把拷贝构造函数和赋值操作符显式的定义为private,但是这样需要很多代码. 于是boost库为大家提供了一个简单的方法:只需要将类继承于noncopyable就可以了. #include "

boost::bind 详解

使用 boost::bind是标准库函数std::bind1st和std::bind2nd的一种泛化形式.其可以支持函数对象.函数.函数指针.成员函数指针,并且绑定任意参数到某个指定值上或者将输入参数传入任意位置. 1. 通过functions和function pointers使用bind 给定如下函数: 1 int f(int a, int b) 2 { 3 return a + b; 4 } 5 6 int g(int a, int b, int c) 7 { 8 return a + b