定義函式物件 (轉)
定義
時間: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
};
int main()
{
GenericNegate negate;
cout<< negate(5.3333); // double
cout<< negate(10000000000i64); // __int64
}
如果用普通的回撥函式實現上述的靈活性是相當困難的。
標準庫中函式物件
C++標準庫定義了幾個有用的函式物件,它們可以被放到STL演算法中。例如,sort()演算法以判斷物件(predicate )作為其第三個引數。判斷物件是一個返回Boolean型結果的模板化的函式物件。可以向sort()傳遞greater<>或者less<>來強行實現排序的升序或降序:
#include
#include
#include
using namespace std;
int main()
{
vector
//..填充向量
sort(vi.begin(), vi.end(), greater
sort(vi.begin(), vi.end(), less
}
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-1001565/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- shell 函式定義函式
- 02_函式定義及使用函式函式
- 如何在函式內部定義函式?函式
- 建構函式定義的隱式型別轉換函式型別
- 兄弟連go教程(11)函式 - 函式定義Go函式
- C++型別轉換時定義非成員函式(轉)C++型別函式
- 在jQuery定義自己函式jQuery函式
- python如何定義函式Python函式
- python---函式定義Python函式
- mysql函式定義語法MySql函式
- qt之函式重定義QT函式
- ts函式約束定義函式
- 第 8 節:函式-函式定義和引數函式
- 什麼是Python函式?如何定義函式?Python函式
- 函式引數 引數定義函式型別函式型別
- 函式定義、函式的引數、函式的預設引數函式
- makefile--函式定義與呼叫函式
- sql server檢視函式定義SQLServer函式
- oracle 過程函式定義字典Oracle函式
- Python巢狀定義函式增強reduce()函式功能Python巢狀函式
- Shell中函式的定義和使用函式
- Python如何定義一個函式Python函式
- 方法(函式)的定義與引數函式
- c語言函式指標的定義C語言函式指標
- JS函式的定義與呼叫方法JS函式
- TS定義陣列 ts宣告函式陣列函式
- 模型的列表定義中,使用函式時如何定義引數?模型函式
- Day10 函式基礎+函式三種定義形式 + 函式的返回值、物件和引數 + 可變長引數函式物件
- 函式物件、物件、原型函式物件原型
- C++入門教程(12):定義函式C++函式
- Python騷操作:動態定義函式Python函式
- TypeScript 定義函式的幾種寫法TypeScript函式
- 函式基本定義和使用‘未完待續函式
- 1 函式極限的嚴格定義函式
- 通過JavaScript定義函式的注意點JavaScript函式
- vue 在methods中定義的函式 not definedVue函式
- 【46】需要型別轉換時請為模版定義非成員函式型別函式
- Oracle檢視錶、儲存過程、觸發器、函式等物件定義語句Oracle儲存過程觸發器函式物件