STL中僞函數、函數對象(functor)初步理解(上)

僞函數或者函數對象只是翻譯的問題,英文全部都是functor,還有些讀物管這個叫函數符。functor作爲C++ STL六大基本組件之一被廣泛使用(其他五個分別是容器、演算法、迭代器、適配器、分配器),那麼,functor的意義在哪裏?或者說它有什麼作用?


這項技術從概念上不難理解,僞函數也好,函數對象也好,都說明了它不是真正的函數,而是一種類似函數作用的東西,在STL裏,我們經常需要對容器內元素進行批量操作,手寫循環確實是個方法,但是,代碼冗餘,而且效率普遍偏低,這就需要一個批量操作方法,能夠對容器內的元素進行批量操作,那麼,怎麼操作,操作什麼,這就需要用戶去定義了,你需要告訴程序,你想要什麼樣的操作,一般人對於這種問題的第一反應就是函數指針,確實,通過傳遞一個函數指針可以讓程序執行特定的操作,這也確實是一個方法,但是按CPP Primer Plus上的原文來說,它有一個很大的弊端,那就是函數指針是必須指定參數以及返回類型的,而STL屬於泛型編程,加入用函數指針來操作的話,是違反泛型思想的本質的,因此,這就需要一個能取代函數指針的東西了,而這個東西就是所謂的函數對象。


函數對象是一種介於對象和函數之間的一個東西,調用方式和函數一樣,但是調用的卻是對象裏的operator ()操作符,這可以給程序帶來三大好處。第一,面相對象裏的模板機制對functor是完全適用的,因此用函數對象可以和STL完全兼容,換句話說,使用functor和泛型的思想相符。第二,函數對象本質上是對象,因此,一個函數對象可以使用類中所封裝的所有數據,而對於函數指針來說,只能使用全局數據,所以,使用functor可以達到數據封裝的目的。第三,functor往往是輕量級代碼,因此,可以完美內聯化,這對於程序效率的提升是非常有利的。基於以上三點,就不難理解爲什麼functor是STL六大組件之一。函數對象可以帶來這麼多好處,那麼在STL編程中當然是要儘量多用了,那麼現在問題來了,假如類在設計的時候沒考慮到和STL的適配怎麼辦?這就需要用到STL functor適配器了,常見的適配器有三個:ptr_fun、mem_fun和mem_fun_ref。這三種適配器分別針對不同的對象,ptr_fun可以把一個全局函數轉化成一個functor,後兩者則分別針對面相對象中的函數和函數指針。


首先看第一個函數適配器,也就是ptr_fun,這個適配器可以把一個全局函數轉化成一個functor,根據sgi上的解釋,ptr_fun實際上是兩個函數,當傳遞的函數具有一個參數的時候,ptr_fun會接受一個函數指針,然後返回一個unary_function類型的函數指針,而傳遞的函數具有兩個參數的時候,它則會返回一個binary_function類型的函數指針。其實,ptr_fun並不神祕,同STL種大多數適配器一樣,它只不過是讓一些函數實現所需要的typedef生效而已,而其他兩個適配器也是具有同樣的作用。


另外兩個適配器都是針對類中的函數,假如容器中所放的是實體,那麼轉換函數符的適配器應該使用mem_fun_ref,假如容器中所存放的是指針,那麼函數符適配器應該使用mem_fun,這是二者唯一的區別。不論是mem_fun_ref還是mem_fun,都接受一個函數指針,然後返回一個函數符指針,由於global function本身就是一個函數指針,因此不需要做取址操作,但是對於對象來說,則必須加“&”操作符,也就是說,在mem_fun_ref內部,必須在函數名前面加上&,這樣纔可以達到傳遞指針的目的。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章