定義函式物件

2022-07-15 17:48:13 字數 1631 閱讀 6763

儘管函式指標被廣泛用於實現函式**,但c++還提供了乙個重要的實現**函式的方法,那就是函式物件。函式物件(也稱「算符」)是過載了「()」操作符的普通類物件。因此從語法上講,函式物件與普通的函式行為類似。

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

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

下面舉例說明如何定義和使用函式物件。首先,宣告乙個普通的類並過載「()」操作符:

class negate  };

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

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

使用函式物件

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

#include

using std::cout;

void callback(int n, negate & neg) 

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

int val = neg(n);

轉化為int val = neg.operator()(n);

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

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

int main() 

本例傳遞整數5和乙個臨時negate物件到callback(),然後程式輸出-5。

模板函式物件

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

class genericnegate

};int main()

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

標準庫中函式物件

c++標準庫定義了幾個有用的函式物件,它們可以被放到stl演算法中。例如,sort()演算法以

判斷物件(predicate object)作為其第三個引數。判斷物件是乙個返回boolean型結果的

模板化的函式物件。可以向sort()傳遞greater<>或者less<>來強行實現排序的公升序或降序:

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

#include //for sort() 

#include

using namespace std;

int main()

STL 函式物件 謂詞 預定義函式物件 函式介面卡

過載函式呼叫操作符的類,其物件常稱為函式物件 function object 即它們是行為類似函式的物件,也叫仿函式 functor 其實就是過載 操作符,使得類物件可以像函式那樣呼叫。注意 函式物件 仿函式 是乙個類,不是乙個函式。函式物件 仿函式 過載了 操作符使得它可以像函式一樣呼叫。分類 假...

STL函式物件之自定義函式物件

如何定義自己的函式物件,它使用於任何的繫結器 要定義自己的繫結器要滿足一定的條件 必須提供引數和返回值的型別。stl為我們提供了兩個結構體 template struct unary function template struct binary function 乙個例子 template str...

物件作為函式引數 類外定義成員函式

一 物件作為函式引數 物件也可以作為函式的引數傳遞給函式,其轉遞方法與傳遞其他型別的資料一樣,可採用 值傳遞和位址傳遞兩種方法。值傳遞時是把 物件的拷貝 而不是本身傳遞給函式,函式中對引數 物件的任何修改都不會影響呼叫該函式的物件本身 而位址傳遞 時,呼叫該函式的物件與引數物件共 用同乙個位址 所以...