C++編程語言為我們帶來了非常大的好處。不過即使是我們經常使用的功能也有很多比較高深的內容值得我們去深入的探討。在這裡我們將會為大家詳細介紹一下C++仿函數的基本概念,方便大家對這一語言的解讀。
C++仿函數這個詞經常會出現在模板庫裡比如 STL),那麼什麼是仿函數呢?
顧名思義:仿函數就是能像函數一樣工作的東西,請原諒我用東西這樣一個代詞,下面我會慢慢解釋。
- void dosome( int i )
這個 dosome 是一個函數,我們可以這樣來使用它: dosome(5);
那麼,有什麼東西可以像這樣工作麼?
答案1:重載了 () 操作符的對象,比如:
- struct DoSome
- {
- void operator()( int i );
- }
- DoSome dosome;
這裡類(對 C++ 來說,struct 和類是相同的) 重載了 () 操作符,因此它的實例 dosome 可以這樣用 dosome(5); 和上面的函數調用一模一樣,不是麼?所以 dosome 就是一個C++仿函數了。
實際上還有答案2:
函數指針指向的對象。
- typedef void( *DoSomePtr )( int );
- typedef void( DoSome )( int );
- DoSomePtr *ptr=&func;
- DoSome& dosome=*ptr;
- dosome(5); // 這裡又和函數調用一模一樣了。
當然,答案3 成員函數指針指向的成員函數就是意料之中的答案了。
C++仿函數的用處
不管是對象還是函數指針等等,它們都是可以被作為參數傳遞,或者被作為變量保存的。因此我們就可以把一個仿函數傳遞給一個函數,由這個函數根據需要來調用這個仿函數有點類似回調)。
STL 模板庫中,大量使用了這種技巧,來實現庫的“靈活”。 比如: for_each, 它的源代碼大致如下:
- template < typename Iterator, typename Functor >
- void for_each( Iterator begin, Iterator end, Fucntor func )
- {
- for( ; begin!=end; begin++ )
- func( *begin );
- }
這個 for 循環遍歷了容器中的每一個元素,對每個元素調用了仿函數 func,這樣就實現了 對“每個元素做同樣的事”這樣一種編程的思想。 特別的,如果仿函數是一個對象,這個對象是可以有成員變量的,這就讓C++仿函數有了“狀態”,從而實現了更高的靈活性。