内联函数/回调函数/仿函数(functor)-------(c++)

回调函数
  回调函数就是一种利用函数指针进行函数调用的过程. 而那个函数在需要的时候,利用传递的地址调用回调函数,这时你可以利用这个机会在回调函数中处理消息或完成一定的操作。
  应用程序提供给Windows系统DLL或其它DLL调用的函数,一般用于截获消息、获取系统信息或处理

异步事件。应用程序把回调函数的地址指针告诉DLL,而DLL在适当的时候会调用该函数。(一般为标

准WindowsAPI的调用方式---__stdcall)
注意: 
  I、  不能显式调用的函数,通过将回调函数的地址传给调用者从而实现调用。
  II、 必须遵守事先规定好参数格式和传递方式,
  III、函数(DLL编制者)和客户程序也必须遵守相同的调用约定。
  V、  一般只有DLL中使用回调函数

关于定义函数指针的声明与函数声明。
void f();// 函数原型
void (*) ();//声明一个返回Void类型无参数函数指针。
unsigned psize = sizeof (void (*) ()); // 获得函数指针的大小
typedef void (*pfv) ();// 为函数指针声明类型定义

[c-sharp]  view plain copy
  1. #include<iostream.h>  
  2.   
  3. void fun(int i,int j)  
  4. {  
  5.   i=10;  
  6.   j=20;  
  7.   cout<<i<<endl<<j<<endl;  
  8. }  
  9. void callfun(void(*p)(int,int),int n,int a,int b)  
  10. {  
  11.   if(n>10)  
  12.     p(a,b);  
  13. }  
  14.   
  15. void main()  
  16. {  
  17.   void (*p) (int ,int ); //定义一个函数指针变量P  
  18.   p=fun;  
  19.   callfun(p,100,0,0);  
  20. }  

附关于C#实现回调函数(借用委托)

[c-sharp]  view plain copy
  1. using System;  
  2. using System.Runtime.InteropServices;  
  3.   
  4. public delegate bool CallBack(int hwnd, int lParam);  
  5.   
  6. public class EnumReportApp {  
  7.   
  8.     [DllImport("user32")]  
  9.     public static extern int EnumWindows(CallBack x, int y);   
  10.   
  11.     public static void Main()   
  12.     {  
  13.         CallBack myCallBack = new CallBack(EnumReportApp.Report);  
  14.         EnumWindows(myCallBack, 0);  
  15.     }  
  16.   
  17.    public static bool Report(int hwnd, int lParam) {   
  18.         Console.Write("Window handle is ");  
  19.         Console.WriteLine(hwnd);  
  20.         return true;  
  21.     }  
  22. }  

附:  API函数的参数采用指向回调函数的指针,其名称中通常会有 lp(长指针)前缀与 Func 后缀的组合。
如: BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)

内联函数
  内联函数是代码被插入到调用者代码串处的函数。如同 #define 宏,内联函数通过避免被调用的

开销来提高执行效率,尤其是它能够通过调用(“过程化集成”)被编译器优化。

 

在函数声明或定义中函数返回类型前加上关键字inline即把min()指定为内联。


优点:
  内联能提高函数的执行效率,省去了函数调用的开销,从而提高函数的
执行效率
缺点:
  如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收
获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大

[c-sharp]  view plain copy
  1. 附:内联函数与#define 宏比较  
  2.   
  3. // 返回 i 的绝对值的宏  
  4. #define unsafe(i) /  
  5. ( (i) >= 0 ? (i) : -(i) )  
  6.   
  7. // 返回 i 的绝对值的内联函数  
  8. inline  
  9. int safe(int i)  
  10. {  
  11. return i >= 0 ? i : -i;  
  12. }  
  13. int f();  
  14.   
  15. void userCode(int x)  
  16. {  
  17. int ans;  
  18.   
  19. ans = unsafe(x++); // 错误!x 被增加两次  
  20. ans = unsafe(f()); // 危险!f()被调用两次  
  21.   
  22. ans = safe(x++); // 正确! x 被增加一次  
  23. ans = safe(f()); // 正确! f() 被调用一次  
  24. }  
  25. 和宏不同的,还有内联函数的参数类型被检查,并且被正确地进行必要的转换。  

 


仿函数(functor)
  仿函数是通过重载()运算符模拟函数形为的类。
 明确两点:
 I、 仿函数不是函数,它是个类;
 II、仿函数重载了()运算符,来达到模拟函数调用效果;

 

 

 

[c-sharp]  view plain copy
  1. 实例:  
  2.  
  3. #include <iostream>  
  4. using namespace std;  
  5.   
  6. const int CMP_LES = -1;  
  7. const int CMP_EQU = 0;  
  8. const int CMP_BIG = 1;  
  9.   
  10. class Comparer  
  11. {  
  12. public:  
  13.            Comparer(int cmpType)  
  14.            {  
  15.                m_cmpType = cmpType;  
  16.            }  
  17.   
  18.           bool operator ()(int num1, int num2) const  
  19.            {  
  20.                bool res;  
  21.   
  22.                switch(m_cmpType)  
  23.                {  
  24.                case CMP_LES:  
  25.                    res = num1 < num2;  
  26.                    break;  
  27.                case CMP_EQU:  
  28.                    res = num1 == num2;  
  29.                    break;  
  30.                case CMP_BIG:  
  31.                    res = num1 > num2;  
  32.                    break;  
  33.                default:  
  34.                    res = false;  
  35.                    break;  
  36.   
  37.                }  
  38.   
  39.                return res;  
  40.            }  
  41.   
  42. private:  
  43.            int m_cmpType;  
  44. };  
  45.   
  46. void Swap(int &num1, int &num2)  
  47. {  
  48.            int temp = num1;  
  49.            num1 = num2;  
  50.            num2 = temp;  
  51. }  
  52.   
  53. void SortArray(int array[], int size, const Comparer &cmp)  
  54. {  
  55.            for (int i = 0; i < size - 1; ++i)  
  56.            {  
  57.                int indx = i;  
  58.   
  59.                for (int j = i + 1; j < size; ++j)  
  60.                {  
  61.                    if (cmp(array[indx], array[j]))  
  62.                    {  
  63.                        indx = j;  
  64.                    }  
  65.                }  
  66.   
  67.                if (indx != i)  
  68.                {  
  69.                    Swap(array[i], array[indx]);  
  70.                }  
  71.            }  
  72. }  
  73.   
  74. void ListArray(int array[], int size)  
  75. {  
  76.            for (int i = 0; i < size; ++i)  
  77.            {  
  78.                cout << array[i] << " ";  
  79.            }  
  80. }  
  81.  
  82. #define ARY_SIZE 10  
  83.   
  84. int main()  
  85. {  
  86.            int array[ARY_SIZE] = {10, 12, 9, 31, 93, 34, 98, 9, 1, 20};  
  87.   
  88.            cout << "The initial array is : ";  
  89.            ListArray(array, ARY_SIZE);  
  90.            cout << endl;  
  91.   
  92.           SortArray(array, ARY_SIZE, Comparer(CMP_BIG));  
  93.            cout << "The ascending sorted array is :";  
  94.            ListArray(array, ARY_SIZE);  
  95.            cout << endl;  
  96.   
  97.           SortArray(array, ARY_SIZE, Comparer(CMP_LES));  
  98.            cout << "The descending sorted array is : ";  
  99.            ListArray(array, ARY_SIZE);  
  100.            cout << endl;  
  101.   
  102.            return 0;  
  103. }  
  104.   
  105. 运行结果:  
  106.   
  107. The initial array is : 10 12 9 31 93 34 98 9 1 20  
  108. The ascending sorted array is :1 9 9 10 12 20 31 34 93 98  
  109. The descending sorted array is : 98 93 34 31 20 12 10 9 9 1  
  110.   
  111.   程序中定义了一个仿函数Comparer,它重重载了()运算符:  
  112.   Comparer::bool operator ()(int num1, int num2) const;  
  113.   这里温习一下运算符重载的方式:  
  114.   ret_type operator opt(array_list);  
  115.   其中,ret_type为运算符重载后返回值的类型,operator为c++运算符重载专用关健字,opt为所要重载的运算符,如+, -, *, /, [], ()...  
  116.   于是我们可以解读Comparer::bool operator ()(int num1, int num2) const的意义:  
  117.   bool限定了()的返回值为布尔类型,(int num1, int num2)指定了运算符()的参数形式,const使得应该运算符可被它的const对象调用。()运算符中根据m_cmpType值返回不同方式下两整数的比较值。  
  118.   
  119.   函数void SortArray(int array[], int size, const Comparer &cmp)用于给数组排序。其中,array[]指定所要排序的数组对象,size限定数组元素个数,cmp为Comparer对象的引用,用作对元素的比较使用,前面使用const修饰是向函数调用都声明,在函数内不会有修改该对象任何数据的形为。注意SortArray中的代码:  
  120.            if (cmp(array[indx], array[j]))  
  121.            {  
  122.                indx = j;  
  123.            }  
  124.   其中,cmp为Comparer类的一个对象,但这里的用法好像它是某个函数的样子。这就是仿函数的真谛。  
  125.   
  126.   别外,void Swap(int &num1, int &num2)完成交换num1与num2值的功能。int &num1表示函数参数使用的引用,用久了c的朋友也许更习惯了void Swap(int *num1, int *num2),但在c++中这个习惯要改了,引用和指针一样高效,但引用要比指针更直观。下面是指针版的Swap函数:  
  127.            void Swap(int *num1, int *num2)  
  128.            {  
  129.                int temp = *num1;  
  130.                *num1 = *num2;  
  131.                *num2 = temp;  
  132.            }  
  133.   实现的功能与程序中使用的一模一样,替换掉程序照样正常工作。仔细比较引用版与指针版的Swap()函数,我相信大多数人会爱上C++的引用版。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值