C 函式物件operator

2021-07-24 04:48:13 字數 3090 閱讀 6586

函式物件:定義了呼叫操作符()的類物件。當用該物件呼叫此操作符時,其表現形式如同普通函式呼叫一般,因此取名叫函式物件。舉個最簡單的例子:

class a 

};

類a中定義了操作符 ( ),a物件呼叫語句在形式上跟以下函式的呼叫完全一樣:

int i = -1;

a func;

cout << func(i);

與普通函式相比,函式物件比函式更加靈活,函式物件的優勢:使用函式物件的典型例子:

1、字串排序規則

在容器set 中對string 進行排序,首先來定義相應的類並定義 () 來規定排序規則:

class sort  

};

然後我們可以用這個類作為引數來初始化set容器:

setmyset;  //帶比較函式的set建構函式,並用函式物件sort初始化

myset.insert("a");

myset.insert("b");

這樣容器內容輸出為:b,a。

2、謂詞函式

謂詞函式通常用來對傳進來的引數進行判斷,並返回布林值。但是一般的函式形式固化,比如字串長度比較只能判斷是否大於乙個確定的長度值。函式物件可以作為謂詞函式,並可以在類初始化時傳遞引數,如字串長度參考值,因此函式物件比普通函式更加靈活。

現在假設我們有一串數字,要從中找出第乙個不小於10的數字。可以定義如下相應的類:

class upper 

bool operator() (int value) const

private:

int m_min;

};

從而這樣呼叫 find_if 函式:

find_if( dest.begin(), dest.end(), upper(10) );

首先生成類 upper 的物件,並用 10 初始化,呼叫find_if 時將用該函式物件進行判斷。

請注意:在呼叫用到函式物件的標準庫演算法時,除非顯式地指定模板型別為傳引用,否則預設情況下函式物件是按值傳遞的!因此,如果傳遞乙個具有內部狀態的函式物件,則被改變狀態的是函式內部被複製的臨時物件,函式結束後隨之消失。真正傳進來的函式物件狀態並為改變。

class b

bool operator() (int)

int getcount() const

private:

int th;

int count;

};

測試如下:

vectorvec;

for( int i = 3; i!= 13; ++i )

vec.push_back(i);

b b(3);

vector::iterator iter = find_if( vec.begin(), vec.end(), b ); //呼叫函式物件,查詢第三個數字

cout<< "3rd:" << *iter 輸出結果為,確實能找到第三個數字(5),但檢視b的狀態時,返回的 count 依然為0,說明:

原則:

不是所有的返回布林值的函式物件都適合作為謂詞函式,因此用作謂詞函式的函式物件,最好不要依賴其內部狀態的改變。

標準庫定義的函式物件

標準庫定義了一組算術、關係與邏輯函式物件類。標準庫還定義了一組函式介面卡,使我們能夠特化或者擴充套件標準庫所定義的以及自定義的函式物件類。這些標準庫函式物件型別是在 functional 標頭檔案中定義的。

plus函式物件的應用:

plusintadd; // intadd為函式物件

int sum = intadd(10, 20); // 使用函式物件相加兩個運算元

plusstringadd; //

string strs = stringadd("ab", "12"); // 使用函式物件相加兩個運算元

函式物件的函式介面卡介面卡分為如下兩類:

1. 繫結器,是一種函式介面卡,它通過將乙個運算元繫結到給定值而將二元函式物件轉換為一元函式物件。

2. 求反器,是一種函式介面卡,它將謂詞函式物件的真值求反。

繫結器

標準庫定義了兩個繫結器介面卡:bind1st 和 bind2nd。每個繫結器接受乙個函式物件和乙個值。

為了計算乙個容器中所有小於或等於 10 的元素的個數,可以這樣給 count_if 傳遞值:

count_if( vec.begin(), vec.end(), bind2nd( less_equal(), 10 ) );

傳給 count_if 的第三個實參使用 bind2nd 函式介面卡,該介面卡返回乙個函式物件,該物件用 10 作右運算元應用 <= 操作符。這個 count_if 呼叫計算輸入範圍中小於或等於 10 的元素的個數。

求反器

標準庫還定義了兩個求反器:not1 和 not2。

為了對 less_equal 函式物件的繫結求反,可以編寫這樣的**:

count_if( vec.begin(), vec.end(),not1( bind2nd(less_equal(), 10 ) ) );

首先將 less_equal 物件的第二個運算元繫結到 10,實際上是將該二元操作轉換為一元操作。再用 not1 對操作的返回值求反,效果是測試每個元素是否 <=。然後,對結果真值求反。這個 count_if 呼叫的效果是對大於 10 的那些元素進行計數。

operator 過載函式

今天在看書時發現了乙個有意思的地方 class textblock char operator size t position private string text int main 對於 類的運算子過載函式 char operator size t position 其返回值是類成員text的引...

拷貝建構函式, operator

我們知道如果程式設計師不寫建構函式,編譯器會自動提供乙個無參建構函式。這個預設的建構函式在會呼叫成員變數的預設建構函式,從而完成物件的初始化。若要覆蓋預設建構函式,我們只需提供乙個自定義的建構函式即可。除預設建構函式外,編譯器還會提供另一種建構函式 拷貝建構函式。當需要根據乙個已有的物件來構造另乙個...

operator引用貌似本物件

friend ostream operator ostream os,const 類名 類定義的 tt operator tt operator int 再定義乙個類定義的 tt operator tt operator int 在定義乙個類定義的 友出引運 出引os常類引用 友入引運 入引is類引...