函數對象和函數指針

函數指針

  • 函數指針:是指向函數的指針變量,在C編譯時,每一個函數都有一個入口地址,那麼這個指向這個函數的函數指針便指向這個地址。

  • 用途:用作調用函數和做函數的參數。

  • 聲明方法:數據類型標誌符 (指針變量名) (形參列表)
    int (*func) (int x); 這裏的(*func)不能去掉括號,去掉括號就是返回值爲int指針的函數聲明。

  • 一般用typedef:
    typedef int (*PF) (int x); PF pf;

  • 用法示例:

      typedef void (*PFT) (int &);
    
      void bar(int &i)
      {
          i++;
          return ;
      }
      
      int main()
      {
          PFT pft=bar;
          std::vector<int> ivec{3, 4, 2, 8, 15, 267};
          std::for_each(ivec.begin(), ivec.end(), bar);
      
          return 0;
      }
    
  • 優點:使程序更加清晰易懂,編碼方便。函數指針是C推崇的,也是鮮明的C的特徵。

函數對象

  • 函數對象,從名字上可以看到是一個對象,它本質上就是一個類對象,但是它的功能和函數極爲相似。所以我們將他稱爲函數對象。通常的做法是定義一個struct或者class,並重載它的operator()即可。

  • 用途:可以等效爲函數指針,但比它更強大。

  • 用法:

      class Inc
      {
      public:
          void operator()(int& a)
          {
              ++a;
          }
      };
    

Inc()就是一個函數對象了。實際上就是調用Inc().()
std::for_each(ivec.begin(), ivec.end(), Inc());

  • 優點:
    • 相比函數指針,性能更高。因爲調用Inc()的operator()實質上是調用這個類成員的成員函數,而這個成員函數默認是inline的。但函數指針就是普通的調用函數,效率低。(這裏要知道inline內聯函數的優勢)

    • 相比函數指針,可以記錄函數狀態,即我們不用全局變量就可以達到記錄狀態的功能,並且更加安全。

        //函數對象
        class Countfrom
        {
        private:
            int &count;
        public:
            Countfrom(int& n):count(n)
            {
            }
            int operator()()
            {
                return count++;
            }
        };
        // 函數指針
        int s = 10;
        int fCountfrom()
        {
            return s++;
        }
         
        int main()
        {
            int state(10);
            int ar[11];
            std::generate_n(ar,11,Countfrom(state));
            // std::generate_n(ar,11,fCountfrom);
            for(int i = 0; i < 11; ++i)
                std::cout<<ar[i]<<std::endl;
            system("pause");
        }
      
    可以看到函數指針要想記錄,需要用全局變量。而函數對象實質是個類對象,可以定義自己的成員變量。只需自己內部的count即可,更加靈活安全。
  • 故我們可以在函數對象內部,定義自己的成員變量,這大大增加了靈活性。

總結:在C++中更推崇函數對象的做法,因爲本質就是類。在STL中有很多這種用法,並且在Effective C++中也有很多泛型編程的講解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章