定義函式物件 (轉)

gugu99發表於2008-03-27
定義函式物件 (轉)[@more@]

定義

時間:2001/02/07 15:22 作者:vckbase

  儘管函式指標被廣泛用於實現函式回撥,但C++還提供了一個重要的實現回撥函式的方法,那就是函式物件。函式物件(也稱“算符”)是過載了“()”運算子的普通類物件。因此從語法上講,函式物件與普通的函式行為類似。

用函式物件代替函式指標有幾個優點,首先,因為物件可以在內部修改而不用改動外部介面,因此設計更靈活,更富有彈性。函式物件也具備有先前結果的資料成員。在使用普通函式時需要將先前呼叫的結果儲存在全程或者本地靜態變數中,但是全程或者本地靜態變數有某些我們不願意看到的缺陷。

其次,在函式物件中能實現內聯呼叫,從而更進一步增強了。這在函式指標中幾乎是不可能實現的。

下面舉例說明如何定義和使用函式物件。首先,宣告一個普通的類並過載“()”運算子:

class Negate

{

public:

int operator() (int n) { return -n;}

};

過載操作語句中,記住第一個圓括弧總是空的,因為它代表過載的運算子名;第二個圓括弧是引數列表。一般在過載運算子時,引數數量是固定的,而過載“()”運算子時有所不同,它可以有任意多個引數。

因為在Negate中內建的操作是一元的(只有一個運算元),過載的“()”運算子也只有一個引數。返回型別與引數型別相同-本例中為int。函式返回與引數符號相反的整數。

使用函式物件

我們現在定義一個叫Callback()的函式來測試函式物件。Callback()有兩個引數:一個為int一個是對類Negate的引用。Callback()將函式物件neg作為一個普通的函式名:

#include

using std::cout;

void Callback(int n, Negate & neg)

{

int val = neg(n); //呼叫過載的運算子“()”

cout << val;

}

不要的程式碼中,注意neg是物件,而不是函式。編譯器將語句

int val = neg(n);

轉化為

int val = neg.operator()(n);

通常,函式物件不定義建構函式和解構函式。因此,在建立和銷燬過程中就不會發生任何問題。前面曾提到過,編譯器能內聯過載的運算子程式碼,所以就避免了與函式呼叫相關的執行時問題。

為了完成上面個例子,我們用主函式main()實現Callback()的引數傳遞:

int main()

{

Callback(5, Negate() ); //輸出 -5

}

本例傳遞整數5和一個臨時Negate物件到Callback(),然後輸出-5。

模板函式物件

從上面的例子中可以看出,其資料型別被限制在int,而通用性是函式物件的優勢之一,如何建立具有通用性的函式物件呢?方法是使用模板,也就是將過載的運算子“()”定義為類成員模板,以便函式物件適用於任何資料型別:如double,_int64或char:

class GenericNegate

{

public:

template T operator() (T t) const {return -t;}

};

int main()

{

GenericNegate negate;

cout<< negate(5.3333); // double

cout<< negate(10000000000i64); // __int64

}

如果用普通的回撥函式實現上述的靈活性是相當困難的。

標準庫中函式物件

C++標準庫定義了幾個有用的函式物件,它們可以被放到STL演算法中。例如,sort()演算法以判斷物件(predicate )作為其第三個引數。判斷物件是一個返回Boolean型結果的模板化的函式物件。可以向sort()傳遞greater<>或者less<>來強行實現排序的升序或降序:

#include // for greater<> and less<>

#include //for sort()

#include

using namespace std;

int main()

{

vector vi;

//..填充向量

sort(vi.begin(), vi.end(), greater() );//降序( descending )

sort(vi.begin(), vi.end(), less() ); //升序 ( ascending )

}

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-1001565/,如需轉載,請註明出處,否則將追究法律責任。

相關文章