传递模板类的成员函数指针及static成员函数

来源:互联网 发布:java开发工具 编辑:程序博客网 时间:2024/06/06 16:41

前几天相中并买下了一本《C++数据结构与算法》,的确是相中了,封面看起来B格就很高,今天把它拿出来抖抖灰,敲了书上P175的一段二叉查找树的代码。突发奇想给遍历成员函数传递一个函数成员指针,用来访问节点数据,并在类内定义成员函数vist,作为默认的访问函数,如下面的BFS遍历,

template <typename T>void BST<T>::breadthFirst(void(*func)(BSTNode<T> *) = &BST<T>::vist){std::queue<BSTNode<T> *> que;BSTNode<T> *p = root;if (p == 0)return;que.push(p);while (!que.empty()){p = que.front();que.pop();if (p->left)que.push(p->left);if (p->right)que.push(p->right);func(p);}}
//BST::vist
template <typename T>inline void BST<T>::vist(BSTNode<T> *node){cout << node->val << ' ';return;}
结果编译时报错:

错误 1error C2440: “默认参数”: 无法从“void (__thiscall BST<int>::* )(BSTNode<T> *)”转换为“void (__cdecl *)(BSTNode<T> *)”

话说以前并没有见到过类似报错,在捣鼓了老半天之后,一拍脑门想到:thiscall 和cdecl,是不是少一个static关键字? 加上!果然就喜闻乐见的编译通过了!


//定义不变,类内的声明加上static关键字
static void vist(BSTNode<T> *);
在网上找了一下,看到这个帖子

http://bbs.csdn.net/topics/390246787

1、类没有实例化前,只能用静态成员函数操作

显然在传递成员函数指针时,并没有实例化的类,所以必须是static成员函数

源代码:

<p></p><pre name="code" class="cpp">/* main.cpp */#include "genBST.h"#include <stdlib.h>#include <time.h>using namespace std;int main(){BST<int> bst;srand((unsigned int)time(NULL));for (int i = 0; i < 20; ++i){int temp = rand() % 100;bst.insert(temp);}bst.inorder();std::cout << endl;bst.preorder();cout << endl;bst.postorder();cout << endl;bst.breadthFirst();cout << endl;int n;//while (cin >> n)//{//BSTNode<int> * p=bst.search(n);//if (p)//cout << p << ' ';//}return 0;}

/* genBST.H */#include <iostream>#include <string>#include <queue>template<typename T>class BSTNode{public:BSTNode(){left = right = 0;}BSTNode(const T &v, BSTNode<T> *l = 0, BSTNode<T> *r = 0){val = v;left = l;right = r;}T val;BSTNode<T> *left, *right;};template <typename T>class BST{private:BSTNode<T> * root;void clear();BSTNode<T> *search(BSTNode<T> *, const T &) const;void preorder(BSTNode<T> *, void(*func)(BSTNode<T> *));void inorder(BSTNode<T> *, void(*func)(BSTNode<T> *) );void postorder(BSTNode<T> *, void(*func)(BSTNode<T> *));public:BST(){root = 0;}~BST(){clear();}bool empty() const{return root == 0;}void preorder(void(*func)(BSTNode<T> *) = &BST<T>::vist){preorder(root,func);}void inorder(void(*func)(BSTNode<T> *) = &BST<T>::vist){inorder(root,func);}void postorder(void(*func)(BSTNode<T> *) = &BST<T>::vist){postorder(root,func);}BSTNode<T> * search(const T &v) const{return search(root, v);}static void vist(BSTNode<T> *);static void del(BSTNode<T> *);void breadthFirst(void(*func)(BSTNode<T> *) = &BST<T>::vist);void insert(const T &);};template <typename T>BSTNode<T> * BST<T>::search(BSTNode<T> *root, const T &v) const{BSTNode<T> *p = root;while (p){if (p->val == v)break;else if (p->val > v)p = p->left;elsep = p->right;}return p;}template <typename T>void BST<T>::breadthFirst(void(*func)(BSTNode<T> *) = &BST<T>::vist){std::queue<BSTNode<T> *> que;BSTNode<T> *p = root;if (p == 0)return;que.push(p);while (!que.empty()){p = que.front();que.pop();if (p->left)que.push(p->left);if (p->right)que.push(p->right);func(p);}}template <typename T>void BST<T>::preorder(BSTNode<T> *root, void(*func)(BSTNode<T> *)){BSTNode<T> *p = root;if (p){func(p);if (p->left)preorder(p->left,func);if (p->right)preorder(p->right,func);}}template <typename T>void BST<T>::inorder(BSTNode<T> *root, void(*func)(BSTNode<T> *)){BSTNode<T> * p = root;if (p){if (p->left)inorder(p->left, func);func(p);if (p->right)inorder(p->right, func);}}template <typename T>void BST<T>::postorder(BSTNode<T> *root, void(*func)(BSTNode<T> *)){BSTNode<T> *p = root;if (p){if (p->left)postorder(p->left, func);if(p->right)postorder(p->right, func);func(p);}}template <typename T>void BST<T>::insert(const T &v){if (!root){root = new BSTNode<T>(v);return;}BSTNode<T> *p = root;while (1){if (p->val == v)return;else if (p->val > v){if (!p->left){p->left = new BSTNode<T>(v);return;}p = p->left;}else{if (!p->right){p->right = new BSTNode<T>(v);return;}p = p->right;}}}template <typename T>inline void BST<T>::vist(BSTNode<T> *node){cout << node->val << ' ';return;}template <typename T>void BST<T>::del(BSTNode<T> *root){delete root;root = 0;}template <typename T>void BST<T>::clear(){breadthFirst(&BST<T>::del);root = 0;}
</pre>



0 0
原创粉丝点击