boost::function用法详解(一)

最近在写代码过程中需要使用boost::function,在此之前并没有接触过boost::function,这里主要记录下对boost::function的学习和理解。

boost::function是一个函数对象的“容器”,概念上像是C/C++中函数指针类型的泛化,是一种“智能函数指针”。它以对象的形式封装了原始的函数指针或函数对象,能够容纳任意符合函数签名的可调用对象。因此,它可以被用于回调机制,暂时保管函数或函数对象,在之后需要的时机在调用,使回调机制拥有更多的弹性。

既然boost::function经常被用于回调机制,我们就先看看什么是回调函数吧.

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

其实,之前博主在实际项目中就使用过回调函数带来的方便。记得当时的需求时这样的:有一个链表用来记录一组数据,最大能记录400条记录,这400条数据能根据用户的选择(支持编号(int),距离(float)进行排序)进行排序显示。当时为了使排序算法更为通用,就使用了回调函数。

我们先来看看c/c++中函数指针在普通函数和类成员函数的使用吧!

 
  1. #include <iostream>

  2.  
  3. using namespace std;

  4.  
  5. class CEventQuery;

  6.  
  7. typedef bool (*CommonFuncPoint)(void); //普通函数指针

  8. typedef bool (CEventQuery::*ClassFuncPoint)(int); //类成员函数指针

  9.  
  10. bool CommonFunc(void)

  11. {

  12. //这是个回调函数,当特定的事件或条件发生

  13. //的时候,会被调用。

  14. cout << "CallBackFunc Common Function Call!" << endl;

  15. //这里会有特定事件或条件发生时需要处理的事

  16. //....

  17. return true;

  18. }

  19.  
  20. class CEventQuery

  21. {

  22. public:

  23. CEventQuery(CommonFuncPoint eventFunc)

  24. :m_Event(eventFunc)

  25. {

  26.  
  27. }

  28.  
  29. ~CEventQuery()

  30. {

  31.  
  32. }

  33.  
  34. void Query(void)

  35. {

  36. //这里会检测某个事件或条件的发生

  37. //比方说这里查询到了事件发生或条件的改变,那么就回调处理函数

  38. m_Event();

  39. }

  40.  
  41. bool DoSomething(int iValue)

  42. {

  43. cout << "Class Function DoSomething Parament : " << iValue << endl;

  44. return true;

  45. }

  46.  
  47. private:

  48. CommonFuncPoint m_Event;

  49. };

  50.  
  51. int main(void)

  52. {

  53. CEventQuery tEventQuery(CommonFunc);

  54.  
  55. tEventQuery.Query();

  56.  
  57. ClassFuncPoint ClassFunc1 = &CEventQuery::DoSomething;

  58. (tEventQuery.*ClassFunc1)(10);

  59.  
  60. tEventQuery.DoSomething(20);

  61.  
  62. return 0;

  63. }

运行结果如下所示:

 
  1. CallBackFunc Common Function Call!

  2. Class Function DoSomething Parament : 10

  3. Class Function DoSomething Parament : 20

不足的地方是,这种方式的调用只适用于函数指针,不适用于非函数指针(比如函数对象),这就是局限性。


与之前使用函数指针不同,function就像是一个函数的容器,也可以把function想象成一个泛化的函数指针,只要符合它声明中的函数类型,任何普通函数,成员函数,函数对象都可以存储在function对象中,然后在任何需要的时候被调用。
 

boost::function能够代替函数指针,并且能能接受函数或函数对象,增加了程序的灵活性。当然,带来好处的同时,也必然有弊端。boost::function相比函数指针来说体积稍大一点,速度上稍慢一点。不过相比于boost::function带来的灵活性相比速度和体积就显得举足轻重了。

查看Boost官方文档,Boost.Function 有两种形式:首选形式和便携式形式, 其语法如下:

首选语法 便携式语法
boost::function<float (int x, int y)> f;
boost::function2<float, int, int> f;

这两种形式等价,大家可以选择一种自己喜欢使用的形式即可(有一些较老的编译器不支持便携式)。
作为示范,我们的例子展示了:普通函数类成员函数函数对象的使用。当然function可以配合bind使用,存储bind表达式的结果,使bind可以被多次调用。目前没用到,下次再补充。

 
  1. #include <iostream>

  2. #include <boost/function.hpp>

  3.  
  4. using namespace std;

  5.  
  6. template<typename Func>

  7. class CFuncDemo

  8. {

  9. public:

  10. CFuncDemo(int iValue)

  11. :m_iValue(iValue)

  12. {

  13. }

  14.  
  15. template<typename CallBackFunc>

  16. void acceptFunc(CallBackFunc Func)

  17. {

  18. m_Func = Func;

  19. }

  20.  
  21. void CommonResult()

  22. {

  23. m_Func(m_iValue);

  24. }

  25.  
  26. template<typename T>

  27. void ClassMemberResult(T &t)

  28. {

  29. m_Func(t, m_iValue);

  30. }

  31.  
  32. void FuncObjResult()

  33. {

  34. m_Func(m_iValue);

  35. }

  36.  
  37. private:

  38. Func m_Func;

  39. int m_iValue;

  40. };

  41.  
  42. //普通函数

  43. void CommonFunc(int iValue)

  44. {

  45. cout << "CallBack Common Function" << endl;

  46. cout << "2 * iValue = " << 2 * iValue << endl;

  47. }

  48.  
  49. //这个类有个成员函数完成类似的功能

  50. class CMultiple

  51. {

  52. public:

  53. void ClassFunc(int iValue)

  54. {

  55. cout << "CallBack Class Member Function" << endl;

  56. cout << "3 * iValue = " << 3 * iValue << endl;

  57. }

  58. };

  59.  
  60. //这里有个函数对象同样也完成对应的功能

  61. class CFuncObj

  62. {

  63. public:

  64. void operator()(int iValue)

  65. {

  66. cout << "CallBack Function Object" << endl;

  67. cout << "4 * iValue = " << 4 * iValue << endl;

  68. }

  69. };

  70.  
  71. int main(void)

  72. {

  73. //作为示范的测试用例,这里我们展示了:普通函数、类成员函数、函数对象的使用

  74.  
  75. //普通函数

  76. CFuncDemo<boost::function<void(int)>> tFuncCommon(10);

  77. tFuncCommon.acceptFunc(CommonFunc);

  78. tFuncCommon.CommonResult();

  79.  
  80. //类成员函数

  81. CMultiple tMember;

  82. CFuncDemo<boost::function<void(CMultiple &, int)>> tFuncClassMember(10);

  83. tFuncClassMember.acceptFunc(&CMultiple::ClassFunc);

  84. tFuncClassMember.ClassMemberResult(tMember);

  85.  
  86. //函数对象

  87. CFuncObj tObj;

  88. CFuncDemo<boost::function<void(int)>> tFuncObj(10);

  89. //tFuncObj.acceptFunc(tObj);

  90. //function使用拷贝语义保存参数,使用ref它允许以引用的方式传递参数

  91. tFuncObj.acceptFunc(boost::ref(tObj));

  92. tFuncObj.FuncObjResult();

  93.  
  94. return 0;

  95. }

下面是测试结果:

 
  1. CallBack Common Function

  2. 2 * iValue = 20

  3. CallBack Class Member Function

  4. 3 * iValue = 30

  5. CallBack Function Object

  6. 4 * iValue = 40

关于boost::function的基本用法就讲解完毕。

原文地址:https://blog.csdn.net/huangjh2017/article/details/71124827

猜你喜欢

转载自blog.csdn.net/weixin_39953289/article/details/81079783
今日推荐