C 函式物件與函式指標不同之處

2021-06-19 09:03:20 字數 2910 閱讀 5397

在c++程式語言中,有很多功能都與c語言相通,比如指標的應用等等。在這裡我們介紹的則是一種類似於函式指標的c++函式物件的相關介紹。c++函式物件不是函式指標。但是,在程式**中,它的呼叫方式與函式指標一樣,後面加個括號就可以了。這是入門級的隨筆,說的是函式物件的定義,使用,以及與函式指標,成員函式指標的關係。

c++函式物件實質上是乙個實現了operator()--括號操作符--的類。例如:

class add  

};  

add add; // 定義函式物件  

cout <

<

add(3,2); // 5 

函式指標版本就是:

int addfunc(int a, int b)  

typedef int (*add) (int a, int b);  

add add = &addfunc;  

cout <

<

add(3,2); // 5 

呵呵,除了定義方式不一樣,使用方式可是一樣的。都是:

cout <

<

add(3,2); 

既然c++函式物件與函式指標在使用方式上沒什麼區別,那為什麼要用函式物件呢?很簡單,函式物件可以攜帶附加資料,而指標就不行了。下面就舉個使用附加資料的例子:

class less  

bool operator()(int value)  

private:  

int n;  

};

使用的時候:

less isless(10);  

cout <

<

isless(9) <

< " " <

<

isless(12); // 輸出 1 0 

這個例子好象太兒戲了,換乙個:

const int size = 5;  

int array[size] = ;  

// 找到小於陣列array中小於10的第乙個數的位置  

int * pa = std::find_if(array, array + size, less(10)); 

// pa 指向 9 的位置  

// 找到小於陣列array中小於40的第乙個數的位置  

int * pb = std::find_if(array, array + size, less(40)); 

// pb 指向 30 的位置 

這裡可以看出c++函式物件的方便了吧?可以把附加資料儲存在函式物件中,是函式物件的優勢所在。

它的弱勢也很明顯,它雖然用起來象函式指標,但畢竟不是真正的函式指標。在使用函式指標的場合中,它就無能為力了。例如,你不能將函式物件傳給qsort函式!因為它只接受函式指標。

要想讓乙個函式既能接受函式指標,也能接受函式物件,最方便的方法就是用模板。如:

template<

typename func>

int count_n(int* array, int size, func func)  

這個函式可以統計陣列中符合條件的資料個數,如:

const int size = 5;  

int array[size] = ;  

cout <

<

count_n(array, size, less(10)); // 2  

用函式指標也沒有問題:  

bool less10(int v)  

cout <

<

count_n(array, size, less10); // 2 

另外,c++函式物件還有乙個函式指標無法匹敵的用法:可以用來封裝類成員函式指標!因為函式物件可以攜帶附加資料,而成員函式指標缺少乙個類實體(類例項)指標來呼叫,因此,可以把類實體指標給函式物件儲存起來,就可以用於呼叫對應類實體成員函式了。

template<

typename o>

class memfun  

void operator()(const char* name)  

private:  

void(o::*pfunc)(const char*);  

o* pobj;  

};  

class a  

};  

a a;  

memfun<

a> call(&a::doit, &a); // 儲存 a::doit指標以便呼叫  

call("kitty"); // 輸出 hello kitty! 

大功告成了,終於可以方便儲存成員函式指標,以備呼叫了。

不過,現實是殘酷的。函式物件雖然能夠保有存成員函式指標和呼叫資訊,以備象函式指標一樣被呼叫,但是,它的能力有限,乙個函式物件定義,最多只能實現乙個指定引數數目的成員函式指標。

標準庫的mem_fun就是這樣的乙個函式物件,但是它只能支援0個和1個引數這兩種成員函式指標。如 int a::func()或void a::func(int)、int a::func(double)等等,要想再多乙個引數如:int a::func(int, double),不好意思,不支援。想要的話,只有我們自已寫了。

而且,就算是我們自已寫,能寫多少個?5個?10個?還是100個(這也太恐怖了)?

好在boost庫提供了boost::function類,它預設支援10個引數,最多能支援50個函式引數(多了,一般來說這夠用了。但它的實現就是很恐怖的:用模板部份特化及巨集定義,弄了幾十個模板引數,偏特化(編譯期)了幾十個函式物件。

c++0x已經被接受的乙個提案,就是可變模板引數列表。用了這個技術,就不需要偏特化無數個c++函式物件了,只要乙個函式物件模板就可以解決問題了。

C 函式物件與函式指標的不同之處

c 函式物件和函式指標之間有何不同之處?它的應用方式是否更加靈活,功能是否更加強大?在這裡我們將會為大家詳細介紹。ad 在c 程式語言中,有很多功能都與c語言相通,比如指標的應用等等。在這裡我們介紹的則是一種類似於函式指標的c 函式物件的相關介紹。c 函式物件不是函式指標。但是,在程式 中,它的呼叫...

C 與C語言的不同之處

本文介紹了c 與c語言的不同之處。常見區別 庫函式 c stdio.h c iostream 輸入 c scanf c cin 輸出 c printf c cout 動態開闢 c malloc c new 釋放 c free c delete 以上是比較常見之處。下面是我在學習c 中認識到的內容 內...

陣列和指標的不同之處

我相信很多初學c語言的人,肯定會以為指標和陣列是等價的,而那些學了一段時間的人或許也分不清兩者之間的區別吧。那麼我有必要和大家千談一下c語言中陣列和指標的不同之處了。1.陣列名對應著一塊記憶體,而不是指向一塊記憶體。其位址與容量在生命週期內保持不變 全域性或棧 只有陣列的內容可變 指標可以隨時指向任...