C++ 模板類使用函數指針

       前幾天重看了C++ primer的第16章,正好同時也複習了樹的操作,於是寫了個二分查找樹的模板類。一開始挺順利,後來想嘗試一下使用函數指針來傳遞遍歷樹的函數,因此有了下面的問題,也從解決方法中學到了很多。

       我想要的實現是這樣的:有一個TravelRecursive函數,專門負責用遞歸的方式遍歷整棵樹,而遍歷的方法(中序、前序、後序)想用函數指針傳進來。對結點的處理函數也想用函數指針傳進來。於是這樣寫:

//class BSTree
template <typename T> class BSTree
{
//member functions
private:
typedef void (BSTree<T>::*KF)(BSTNode<T>* node);

        typedef void (BSTree<T>::*PF)(BSTNode<T>* node, KF processFun);

. . . . . .

public:

       void TravelRecursive(PF pf, KF processFun);  

        void PreOderRecursive(BSTNode<T>* node, KF processFun);   //前序遞歸遍歷函數

        void process(BSTNode<T>* node);   //處理結點的函數

}

先用typedef定義了函數指針類型KF和PF。KF和PF的前面之所以要加上BSTree<T>::的作用域,是因爲我希望這個函數指針指向的函數是這個模板類的函數成員,因此需要加上這個作用域。

然後,我們來看一下TravelRecursive函數是如何使用函數指針的。

一開始我是這樣寫的:

template <typename T> void BSTree<T>::TravelRecursive(PF pf, KF process)
{
pf(this->root, process);
}

然後這樣調用:tree.TravelRecursive(&BSTree<int>::PosOderRecursive, &BSTree<int>::process);

運行的時候就報錯了:error C2064: term does not evaluate to a function taking 1 arguments

這個錯誤單是看描述根本不明所以。後來請教了高手,高手只說了怎麼寫,但沒說爲什麼。於是自己想了一會,明白是哪裏出了問題。

回到函數TravelRecursive的調用,我傳入的是&BSTree<int>::PosOderRecursive,那麼PF指向的確是這個函數PosOderRecursive。但調用這個函數時,我寫的是pf(this->root, process),這時就會有問題了。我們平時調用函數的時候,總是a.fun(),這樣其實隱式地給fun函數傳入了一個this參數,而現在因爲傳的時候只用作用域的方式指明瞭函數的地址,所以如果只是pf(this->root, process)這樣去調用的話,會缺少this參數,因此就出現了上述的錯誤。

現在把代碼做如下的修改:

template <typename T> void BSTree<T>::TravelRecursive(PF pf, KF process)
{
(this->*pf)(this->root, process);
}

顯示地給pf指向的函數傳入this參數,這樣就能運行正確了。



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