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++的引用版。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM