18.C++-[ ]操作符使用 、函數對象與普通函數區別(詳解)


在上章17.C++-string字符串類(詳解)學習了string類,發現可以通過[ ]重載操作符訪問每個字符

比如:

string s="SAD";

for(int i=0,i< s.length();i++)
cout<<s[i]<<endl;

 

接下來,我們來自己寫個[ ]重載操作符,來模擬string類

#include <iostream>
#include "string.h"

class string
{
private:
   char *str;
   int len;

public:
    string(const char *p=0)
    {
      if(p!=NULL)
      {
       len=strlen(p);
       str = new char[len];
       strcpy(str,p);
      }
      else
      {
        len=0;
        str = new char[1];
        str[0]='\0';
      }  
    }
    char& operator [](int i)
    {
    return str[i];
    }

    int length()
    {
     return len;
    }
};

int main()
{
       string s="SAD";
       for(int i=0;i< s.length();i++)
       std::cout << s[i] << std::endl;

       return 0;
} 

運行打印:

S
A
D

 

函數對象

  • 函數對象是指該對象具備函數的行為
  • 函數對象,是通過()調用操作符聲明得到的,然后便能通過函數方式來調用該對象了.
  • ()調用操作符可以定義不同參數的多個重載函數
  • ()調用操作符只能通過類的成員函數重載(不能通過全局函數)
  • 函數對象用於在工程中取代函數指針

比如,定義一個函數對象t:

class Test{
public:
      void operator () (void)  //通過()重載操作符,來使對象具備函數的行為
     {
              cout<<"hello"<<endl;
     }
};

int main()
{
       Test t;
       t();          //打印"hello"
} 

 

函數對象與普通函數區別

函數對象

可以封裝自己的成員以及其它函數,所以能夠更好的面向對象.

普通函數

往往只具備邏輯關系,並且沒有固定的成員,因為普通函數一被調用完后,里面的內容便被摧毀了,除非使用全局變量,但是全局變量又不具備封裝性.

接下來,我們來個普通函數函數對象的示例,便知道兩者的區別了.

需求如下:

  • 通過一個函數,來獲取斐波那契數列每項的值
  • 每調用一次函數,便返回一個值
  • 可以重復使用

普通函數實例:

#include <iostream>           
using namespace std;

int cnt0=0;
int cnt1=1;

void fib_set(int n)          //設置斐波那契數列為哪一項,使fib()能重復使用
{
     cnt0=0;
     cnt1=1;
     for(int i=0;i<n;i++)
     {
            int tmp=cnt1;
            cnt1=cnt0+cnt1;
            cnt0=tmp;
     }
}

int fib()              //計算出一項值
{
  int tmp=cnt1;
  cnt1=cnt0+cnt1;
  cnt0=tmp;

  return tmp;
}

int main()
{
  for(int i=0;i<5;i++)
  cout<<fib()<<endl;    //打印1~5項值

  fib_set(0);                  //從新設置項數位0

  for(int i=0;i<5;i++)
  cout<<fib()<<endl;    //再次打印1~5項值,使它能重復使用

  return 0;     
} 

運行打印:

1
1
2
3
5
1
1
2
3
5

從上面代碼可以看到,通過普通函數實現的需求,還需要兩個全局變量才行,這在大項目里,完全不可取的,若項目里,像這樣的模塊多的話,那得有多少個全局變量啊?並且這些全局變量能夠隨意被破壞,沒有一點封裝性.

 

接下來,通過函數對象來完成這個需求:

#include <iostream>           
using namespace std;

class Fib{
private:
       int cnt0;
       int cnt1;
public:
       Fib(int n=0)
       {
          cnt0=0;
          cnt1=1;
       }

       void operator =(int n)
       {
          cnt0=0;
          cnt1=1;      
          for(int i=0;i<n;i++)
          {
             int tmp=cnt1;
             cnt1+=cnt0;
             cnt0=tmp;
          }
       }

       int operator () ()
       {
             int tmp=cnt1;
             cnt1+=cnt0;
             cnt0=tmp;

              return cnt0;
       }

};

int main()
{
  Fib  fib;
  for(int i=0;i<5;i++)
  cout<<fib()<<endl;    //打印1~5項值

  fib=0;                        //從新設置項數為0

  for(int i=0;i<5;i++)
  cout<<fib()<<endl;    //打印1~5項值

  return 0;     
} 

運行打印:

1
1
2
3
5
1
1
2
3
5

從上面代碼看到,使用函數對象后,便不需要使用全局變量了.


免責聲明!

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



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