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参数,这样就能运行正确了。



©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页