在上章17.C++-string字元串類(詳解)學習了string類,發現可以通過[ ]重載操作符來訪問每個字元。 比如: 接下來,我們來自己寫個[ ]重載操作符,來模擬string類 運行列印: 函數對象 函數對象是指該對象具備函數的行為 函數對象,是通過()調用操作符聲明得到的,然後便能通過函數 ...
在上章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
從上面代碼看到,使用函數對象後,便不需要使用全局變數了.