zoukankan      html  css  js  c++  java
  • C++仿函数(functor)详解

    C++仿函数(functor)详解

      所谓的仿函数(functor),是通过重载()运算符模拟函数形为的类。

      因此,这里需要明确两点:

      1 仿函数不是函数,它是个类;

      2 仿函数重载了()运算符,使得它的对你可以像函数那样子调用(代码的形式好像是在调用

    函数)。

      看下面的实例:

    #include <iostream>

    using namespace std;

    const int CMP_LES = -1;

    const int CMP_EQU = 0;

    const int CMP_BIG = 1;

    class Comparer

    {

    public:

               Comparer(int cmpType)

               {

                   m_cmpType = cmpType;

               }

              bool operator ()(int num1, int num2) const

               {

                   bool res;

                   switch(m_cmpType)

                   {

                   case CMP_LES:

                       res = num1 < num2;

                       break;

                   case CMP_EQU:

                       res = num1 == num2;

                       break;

                   case CMP_BIG:

                       res = num1 > num2;

                       break;

                   default:

                       res = false;

                       break;

                   }

                   return res;

               }

    private:

               int m_cmpType;

    };

    void Swap(int &num1, int &num2)

    {

               int temp = num1;

               num1 = num2;

               num2 = temp;

    }

    void SortArray(int array[], int size,const Comparer &cmp)

    {

               for (int i = 0; i < size - 1; ++i)

               {

                   int indx = i;

                   for (int j = i + 1; j < size; ++j)

                   {

                       if (cmp(array[indx], array[j]))

                       {

                           indx = j;

                       }

                   }

                   if (indx != i)

                   {

                       Swap(array, array[indx]);

                   }

               }

    }

    void ListArray(int array[], int size)

    {

               for (int i = 0; i < size; ++i)

               {

                   cout << array << " ";

               }

    }

    #define ARY_SIZE 10

    int main()

    {

               int array[ARY_SIZE] = {10, 12, 9, 31, 93, 34, 98, 9, 1, 20};

               cout << "The initial array is : ";

               ListArray(array, ARY_SIZE);

               cout << endl;

              SortArray(array, ARY_SIZE, Comparer(CMP_BIG));

               cout << "The ascending sorted array is :";

               ListArray(array, ARY_SIZE);

               cout << endl;

              SortArray(array, ARY_SIZE, Comparer(CMP_LES));

               cout << "The descending sorted array is : ";

               ListArray(array, ARY_SIZE);

               cout << endl;

               return 0;

    }

    运行结果:

    The initial array is : 10 12 9 31 93 34 98 9 1 20

    The ascending sorted array is :1 9 9 10 12 20 31 34 93 98

    The descending sorted array is : 98 93 34 31 20 12 10 9 9 1

      程序中定义了一个仿函数Comparer,它重重载了()运算符:

      Comparer::bool operator ()(int num1, int num2) const;

      这里温习一下运算符重载的方式:

      ret_type operator opt(array_list);

      其中,ret_type为运算符重载后返回值的类型,operator为c++运算符重载专用关健字,opt为所要重载的运算符,如+, -, *, /, [], ()...

      于是我们可以解读Comparer::bool operator ()(int num1, int num2) const的意义:

      bool限定了()的返回值为布尔类型,(int num1, int num2)指定了运算符()的参数形式,const使得应该运算符可被它的const对象调用。()运算符中根据m_cmpType值返回不同方式下两整数的比较值。

      函数void SortArray(int array[], int size, const Comparer &cmp)用于给数组排序。其中,array[]指定所要排序的数组对象,size限定数组元素个数,cmp为Comparer对象的引用,用作对元素的比较使用,前面使用const修饰是向函数调用都声明,在函数内不会有修改该对象任何数据的形为。注意SortArray中的代码:

               if (cmp(array[indx], array[j]))

               {

                   indx = j;

               }

      其中,cmp为Comparer类的一个对象,但这里的用法好像它是某个函数的样子。这就是仿函数的真谛。

      别外,void Swap(int &num1, int &num2)完成交换num1与num2值的功能。int &num1表示函数参数使用的引用,用久了c的朋友也许更习惯了void Swap(int *num1, int *num2),但在c++中这个习惯要改了,引用和指针一样高效,但引用要比指针更直观。下面是指针版的Swap函数:

               void Swap(int *num1, int *num2)

               {

                   int temp = *num1;

                   *num1 = *num2;

                   *num2 = temp;

               }

      实现的功能与程序中使用的一模一样,替换掉程序照样正常工作。仔细比较引用版与指针版的Swap()函数,我相信大多数人会爱上C++的引用版。

  • 相关阅读:
    Web 应用程序中的安全向量 – ASP.NET MVC 4 系列
    成员资格、授权 – ASP.NET MVC 4 系列
    数据注解和验证 – ASP.NET MVC 4 系列
    表单和 HTML 辅助方法– ASP.NET MVC 4 系列
    模型(Model)– ASP.NET MVC 4 系列
    Razor 视图引擎 – ASP.NET MVC 4 系列
    视图(View) – ASP.NET MVC 4 系列
    控制器(Controller) – ASP.NET MVC 4 系列
    简介 – ASP.NET MVC 4 系列
    一般处理程序处理图片(动态给图片加上水印、保存缩略图、验证码)
  • 原文地址:https://www.cnblogs.com/johnnyflute/p/3812912.html
Copyright © 2011-2022 走看看