Chinaunix首页 | 论坛 | 博客
  • 博客访问: 581069
  • 博文数量: 104
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1559
  • 用 户 组: 普通用户
  • 注册时间: 2014-08-21 00:58
个人简介

锻炼精神,首先要锻炼肉体

文章分类

全部博文(104)

文章存档

2018年(1)

2016年(1)

2015年(101)

2014年(1)

我的朋友

分类: C/C++

2015-05-14 11:14:53

boost 中的 function,bind ,shared_from_this 这三个方法常常会在一起使用,
并且经常用在回调函数中。这里所说的回调函数就是在一个主函数中,根据不同的情景来通过函数指针来调用不同情景下面的函数。

普通 c++98 通过函数指针来实现回调函数的示例

点击(此处)折叠或打开

  1. #include <iostream>
  2. #include <cstdio>

  3. using namespace std ;

  4. typedef void (* fun_t)(void) ;



  5. void fun0(void)
  6. {
  7.     cout << "fun0 called " << endl ;
  8. }

  9. void fun1 ( void )
  10. {
  11.     cout << "fun1 called " << endl ;
  12. }

  13. void fun2 ( void )
  14. {
  15.     cout << "fun2 called " << endl ;
  16. }

  17.  
  18. void (*cb_fun_list[3])(void) = {fun0 ,fun1 , fun2} ;
  19.     
  20.  

  21. void call_back ( int i )
  22. {
  23.     fun_t funPtr ;
  24.     
  25.     if (i < 0 || i > 2 )
  26.     {
  27.         cout << " illegal function number " << endl ;
  28.         return ;
  29.     }
  30.     funPtr = cb_fun_list[i] ;
  31.     
  32.     funPtr () ;
  33.     
  34. }


  35. int main ()
  36. {
  37.     
  38.     call_back ( 2 ) ;
  39.     call_back ( 0 ) ;
  40.     call_back ( 1 ) ;
  41.     
  42.     return 0 ;
  43. }

 boost 使用示例
个人觉得下面的这个例子除了演示,bind 如何绑定带有参数的方法,并将其与以 function<...> 为参数的
方法对接之外,还有如何使用 shared_from_this () 没有实用价值,
因为我们在编程中很少会用到,类自己定义一个回调函数来回调自己类中的成员方法的。 

回调方法通常应用与2或2个以上的类(结构体) 中的一个类中需要调用bind 方法而需要获得另一个类的对象实例传入
这种情况。比如说第三个例子中所讲的那样,不过第三个例子中没有实现 bind 方法中关于参数传递的处理。

关于 shared_from_this () , 这个方法通常是在类内部来使用,这个方法是用来返回一个 shared_ptr 的指针,
也就是我们常使用到的“智能指针”中最有用的。同时如果要想让 shared_ptr 对应的 T 是当前类的类型的话,
应该让当前的类继承 boost::enable_shared_from_this 这个类作为基类,同时在 enabled_shared_from_this 
后面类模板声明的时候,传入当前的类 , 即
class TestObj : public boost::enable_shared_from_this
{....} ;

还有一点值得注意的便是:
通过上述方法声明的类实例的创建,不能够使用简单的
TestObj testObj (...);
TestObj *testObjPtr = new TestObj () ; 
这种方法进行创建,因为 TestObj 继承了 enable_shared_from_this ,
所以它的初始化方法必须要在某种程度上按照 boost::enable_shared_from_this 的套路来,
所以,应该使用 shared_ptr 的方法来创建指向该对象的指针对象,然后通过指针对象来调用类实例中声明、定义一系列的方法。

点击(此处)折叠或打开

  1. #include <iostream>
  2. #include <cstdio>

  3. #include <boost/function.hpp>
  4. #include <boost/bind.hpp>
  5. #include <boost/enable_shared_from_this.hpp>

  6. using namespace std ;

  7.  class obj : public boost::enable_shared_from_this<obj>
  8. {
  9.     public :
  10.         void runCallBack ( boost::function<int(int,int)> f , int x , int y )
  11.         {
  12.             cout << f( x, y ) << endl ;
  13.         }

  14.         int myadd ( int x , int y )
  15.         {
  16.              return x+y ;
  17.         }
  18.     
  19.         void setCallBack ( int x , int y )
  20.         {
  21.             
  22.             runCallBack( boost::bind( &obj::myadd , shared_from_this () , _1 , _2 ) ,x , y ) ;
  23.         }
  24.         
  25.         private :
  26.             boost::function<int( int ,int )> f;
  27.             
  28. } ;

  29. int main ()
  30. {
  31.     
  32.     boost::shared_ptr<obj> pObj ( new obj ()) ;
  33.     
  34.     pObj->setCallBack(999, 1) ;
  35.     
  36.  
  37.     return 0 ;
  38. }

boost 使用实例
虽然这仅仅是个简单的例子,但是我们可以把情况想象的更加复杂一些,
比如说 Manager 相当于是 RPC 框架中的服务器端的方法调用引擎,
当 Client 端给出需要远程调用的 function -- name , parameter-list 之后,将这些消息通过 socket 封装成消息
传递给服务器端的时候,服务器端的引擎 Manager 可以根据 function <>这个方法来锁定到应该调用哪一个方法来运行。
并把运行之后的结果同样包装成消息,并通过 socket 回复给请求的client。

不过上述的描述还需要大量的代码作为支撑,比如  client server 之间需要定义通信的协议以及 RPC 远程调用的方法的接口描述文件。
这个接口描述文件,可以将它们理解为 server 端为 client 端所提供的可调用方法的清单,同时 server 端可以通过类似于 register
的方法来将所有的方法函数以 function <> 的方式传入到一个 std::vector > 里面.
 

点击(此处)折叠或打开

  1. #include <boost/shared_ptr.hpp>
  2. #include <boost/enable_shared_from_this.hpp>
  3. #include <boost/function.hpp>
  4. #include <boost/bind.hpp>

  5. #include <cstdio>
  6. #include <cstdlib>
  7. #include <iostream>
  8. #include <string>
  9. #include <vector>

  10. using namespace std ;
  11. using namespace boost ;

  12. class Manager
  13. {
  14. public :
  15.     Manager ( )
  16.     {}

  17.     void registerCallBack ( boost::function<void ()> f )
  18.     {
  19.         cout << " in manager call input function " << endl ;
  20.         fds.push_back(f) ;
  21.     }

  22.     void runCallBack ()
  23.     {
  24.         cout<< "running method defined in Node" << endl ;

  25.         for ( int i = 0;i < fds.size() ; i++ )
  26.         {
  27.             boost::function<void()> f = fds[i] ;
  28.             f() ;
  29.         }

  30.         fds.clear() ;
  31.     }


  32. private :
  33.     std::vector<boost::function<void()> > fds ;

  34. } ;

  35. class Node : public boost::enable_shared_from_this<Node>
  36. {
  37. public :
  38.     Node () {}
  39.     Node ( Manager *managerPtr )
  40.     {
  41.         pManager = managerPtr ;
  42.     }
  43.     void Aimer ( )
  44.     {
  45.         cout << " Aimer : hello i am Aimer " << endl ;
  46.     }

  47.     void Kokia ( )
  48.     {
  49.         cout << " Kokia : hello i am Kokia " << endl ;
  50.     }

  51.     void Kylin ( )
  52.     {
  53.         cout << " Kylin Zhang : ..... - _ - ......" << endl ;
  54.     }

  55.     void start ()
  56.     {
  57.         cout << " in method start " << endl ;
  58.         pManager->registerCallBack(boost::bind(&Node::Aimer , shared_from_this() )) ;
  59.          pManager->registerCallBack(boost::bind(&Node::Kokia , shared_from_this())) ;
  60.          pManager->registerCallBack(boost::bind (&Node::Kylin , shared_from_this ())) ;
  61.     }

  62.     Manager *pManager ;
  63. } ;

  64. class Obj : public boost::enable_shared_from_this<Obj>
  65. {
  66. public :
  67.     Obj ( Manager *pManager )
  68.     {
  69.         managerPtr = pManager ;
  70.     }

  71.     void start()
  72.     {
  73.         managerPtr->registerCallBack( boost::bind (&Obj::func1 , shared_from_this ()) ) ;
  74.         managerPtr->registerCallBack( boost::bind ( &Obj::func2 , shared_from_this () )) ;
  75.     }

  76.     void func1()
  77.     {
  78.         cout << "func1 running "<< endl ;
  79.     }

  80.     void func2 ()
  81.     {
  82.         cout << "func 2 running " << endl ;
  83.     }

  84. private :
  85.     Manager* managerPtr ;
  86. } ;


  87. int main ()
  88. {
  89.     Manager* pManager = new Manager() ;

  90.     

  91.     boost::shared_ptr<Node> nodePtr ( new Node ( pManager) ) ;
  92.     
  93.     
  94.     boost::shared_ptr<Obj> objPtr ( new Obj (pManager) ) ;


  95.     cout << " now i would like register methods defined in class Node into Manager function list " << endl ;
  96.     nodePtr->start() ;
  97.     cout << " now register methods in class Obj into Manager , by input parameter the pointer of class Manager instance " << endl ;
  98.     objPtr->start () ;

  99.     cout <<" ------------------------ run method----------------------------" << endl ;
  100.     pManager->runCallBack() ;

  101.  
  102.     return 0 ;
  103. }
end
阅读(3915) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~