error: 函数调用缺少参数列表;请使用“&BinTree<char>::_PrintNode”创建指向成员的指针

本文探讨了使用成员函数指针在二叉树遍历中的常见错误,并提供了解决方案。主要介绍了如何正确地将成员函数作为参数传递,包括将成员函数声明为静态或非成员函数的方法。

在写二叉树的遍历时,错误代码代码如下:

class BinTree
{
public:
    typedef void(*pFun)(pNode);
    void PreVisit()
    {
        _PreVisit(_pRoot,_PrintNode);
    }
protected:
    void _PrintNode(pNode pd)
    {
        cout << pd->_data << endl;
    }

    void _PreVisit(pNode pd,pFun pf)
    {
        if (_pRoot)
        {
            pf(_pRoot);
            _PreVisit(_pRoot->_left,pf);
            _PreVisit(_pRoot->_right,pf);
        }       
    }
private:
    pNode _pRoot;
};

错误原因:
静态成员函数的地址可用普通函数指针储存,而普通成员函数地址需要用类成员函数指针来储存,因为普通成员函数要执行时我们必须要确定他是属于哪个类对象才能执行,而类的static函数是不属于这个类的,他是在编译器编译时期就已经确定的,普通成员函数是在有了类对象之后才能执行。

类的成员函数指针作为参数传递给其他函数和普通函数指针的传递是不同的,普通函数指针的传递只要在参数声明中声明是相同参数个数、类型和相同返回类型的函数指针int (*p)(int),传递时只需传函数名就可以了。可是传递成员函数指针用此方法却不能工作。指针是指向一些内存地址的变量,既可以是数据的地址也可以是函数的地址。C++的 成员指针遵从同样的原则。但在类内部没有地址;选择一个类的成员意味着在类中偏移。只有把这个偏移和具体对象的开始地址结合,才能得到实际地址。成员指针的语法要求选择一个对象的同时逆向引用成员指针。
当然,可以把成员函数声明为static(静态函数),这样传递它的指针就像传递普通函数一样。

解决方法:
把_PrintNode改为static函数或非成员函数即可

对给定的二叉查找树,均有多个不同的数组可以导致生成这棵树。 比如拥有1~7为数据且为满二叉树的二叉查找树,可以由 数组{4,2,6,1,3,5,7}或{4,2,1,3,6,5,7}生成(还有其他可能的数组)。 这道题是计算到底有多少个数组可以生成指定的二叉查找树。 具体实现BinarySearchTree类中,如下的函数: int numWaysToGetBST(int mod_num): 前置条件:二叉查找树已存在。 输入:mod_num为要取的模数,可假设为素数。 功能:计算有多少个数组可以生成这个二叉查找树。由于答案的数字很大,因此答案取模mod_num。 输出:回传如功能描述的答案(记住取模 mod_num)。 后置条件:二叉查找树没变化。#include <iostream> using namespace std; template <class T> class VecList{ private: int capacity; int length; T* arr; void doubleListSize(){ T * oldArr = arr; arr = new T[2*capacity]; capacity = 2 * capacity; for(int i=0;i<length;i++){ arr[i] = oldArr[i]; } delete [] oldArr; } public: VecList(){ length = 0; capacity = 100; arr = new T[capacity]; } VecList(T* a, int n){ length = n; capacity = 100 + 2*n; arr = new T[capacity]; for(int i=0;i<n;i++){ arr[i] = a[i]; } } ~VecList(){ delete [] arr; } int getLength(){ return length; } bool isEmpty(){ return length==0; } void insertEleAtPos(int i, T x){ if(length==capacity) doubleListSize(); if(i > length || i < 0) throw "Illegal position"; for(int j=length;j>i;j--) arr[j] = arr[j-1]; arr[i] = x; length++; } T deleteEleAtPos(int i){ if(i >= length || i < 0) throw "Illegal position"; T tmp = arr[i]; for(int j=i;j<length-1;j++) arr[j] = arr[j+1]; length--; return tmp; } void setEleAtPos(int i, T x){ if(i >= length || i < 0) throw "Illegal position"; arr[i] = x; } T getEleAtPos(int i){ if(i >= length || i < 0) throw "Illegal position"; return arr[i]; } int locateEle(T x){ for(int i=0;i<length;i++){ if(arr[i]==x) return i; } return -1; } void printList(){ for(int i=0;i<length;i++) cout << arr[i] << " "; } }; template <class T> struct DNode{ T data; DNode<T>* next; }; template <class T> class LinkStack{ private: DNode<T>* top; int length; public: LinkStack(){ top = NULL; length = 0; } ~LinkStack(){ while(top!=NULL){ DNode<T>* tmp = top; top = top->next; delete tmp; } } int getLength(){ return length; } bool isEmpty(){ return length==0; } void push(T x){ DNode<T>* tmp = new DNode<T>; tmp->data = x; tmp->next = top; top = tmp; length++; } T pop(){ if(length==0) throw "Stack Empty!"; DNode<T>* tmp = top; top = top->next; T tmpData = tmp->data; delete tmp; length--; return tmpData; } T getTop(){ if(length==0) throw "Stack Empty!"; return top->data; } void printStack(){ cout << "Stack top: "; DNode<T>* tmp = top; while(tmp!=NULL){ cout << tmp->data << " "; tmp = tmp->next; } cout << ":stack bottom" << endl; } }; template <class T> class LinkQueue{ private: DNode<T>* front; DNode<T>* back; int length; public: LinkQueue(){ front = new DNode<T>; front->next = NULL; back = front; length = 0; } ~LinkQueue(){ while(front!=NULL){ back = front; front = front->next; delete back; } } int getLength(){ return length; } bool isEmpty(){ return length==0; } void enQueue(T x){ DNode<T>* tmpN = new DNode<T>; tmpN->data = x; tmpN->next = NULL; back->next = tmpN; back = tmpN; length++; } T deQueue(){ if(length==0) throw "Queue Empty!"; DNode<T>* tmpN = front->next; front->next = tmpN->next; T tmpD = tmpN->data; delete tmpN; length--; if(length==0) back = front; return tmpD; } T peekQueue(){ if(length==0) throw "Queue Empty!"; return front->next->data; } void printQueue(){ cout << "Front of queue: "; DNode<T>* tmp = front->next; while(tmp!=NULL){ cout << tmp->data << " "; tmp = tmp->next; } cout << ": back of queue" << endl; } }; template <class T> class BinTree{ private: T data; BinTree<T>* left; BinTree<T>* right; BinTree<T>* parent; public: BinTree(){ left = NULL; right = NULL; parent = NULL; } BinTree(T x){ data = x; left = NULL; right = NULL; parent = NULL; } ~BinTree(){ } void addLChild(BinTree<T>* bt){ left = bt; if(bt==NULL) return; bt->parent = this; } void addLChild(T x){ BinTree<T>* bt = new BinTree<T>(x); addLChild(bt); } void addRChild(BinTree<T>* bt){ right = bt; if(bt==NULL) return; bt->parent = this; } void addRChild(T x){ BinTree<T>* bt = new BinTree<T>(x); addRChild(bt); } T getData(){ return data; } void setData(T x){ data = x; } BinTree<T>* getLChild(){ return left; } BinTree<T>* getRChild(){ return right; } BinTree<T>* getParent(){ return parent; } void setParent(BinTree<T>* bt){ parent = bt; } void printPreOrderR(){ cout << data << " "; if(left!=NULL) left->printPreOrderR(); if(right!=NULL) right->printPreOrderR(); } void printPostOrderR(){ if(left!=NULL) left->printPostOrderR(); if(right!=NULL) right->printPostOrderR(); cout << data << " "; } void printInOrderR(){ if(left!=NULL) left->printInOrderR(); cout << data << " "; if(right!=NULL) right->printInOrderR(); } void printLevelOrder(){ LinkQueue<BinTree<T> *> q; q.enQueue(this); while(!q.isEmpty()){ BinTree<T>* tmpN = q.deQueue(); cout << tmpN->data << " "; if(tmpN->left!=NULL) q.enQueue(tmpN->left); if(tmpN->right!=NULL) q.enQueue(tmpN->right); } } }; /* UPLOAD START */ template <class T> class BinarySearchTree{ // T better have its comparison operators overloaded. // we assume no duplicate elements // use an empty root node private: BinTree<T>* root; int nodeCount; BinTree<T>* findParent(T x){ if(nodeCount==0){ return NULL; } BinTree<T>* bt = root->getRChild(); BinTree<T>* btParent = bt->getParent(); while(bt!=NULL){ if(bt->getData()==x){ return bt->getParent(); } else if(bt->getData() > x){ btParent = bt; bt = bt->getLChild(); } else{ btParent = bt; bt = bt->getRChild(); } } return btParent; } public: BinarySearchTree(){ root = new BinTree<T>(); nodeCount = 0; } BinarySearchTree(T* arr, int n){ // insert whole array root = new BinTree<T>(); nodeCount = 0; if(n==0) return; for(int i=0;i<n;i++){ insertData(arr[i]); } } ~BinarySearchTree(){ // LinkQueue destroying every node LinkQueue<BinTree<T>*> q; q.enQueue(root); while(!q.isEmpty()){ BinTree<T>* bt = q.deQueue(); if(bt->getLChild()!=NULL) q.enQueue(bt->getLChild()); if(bt->getRChild()!=NULL) q.enQueue(bt->getRChild()); delete bt; } } bool isEmpty(){ return nodeCount==0; } void insertData(T x){ if(nodeCount==0){ nodeCount++; root->addRChild(x); return; } if(searchData(x)) return; BinTree<T>* btP = findParent(x); if(btP->getData()<x) btP->addRChild(x); if(btP->getData()>x) btP->addLChild(x); nodeCount++; } bool searchData(T x){ if(nodeCount==0) return false; BinTree<T>* btP = findParent(x); if(btP==root) return true; if(btP->getData()<x) return (btP->getRChild()!=NULL); if(btP->getData()>x) return (btP->getLChild()!=NULL); } bool deleteData(T x){ if(nodeCount==0) return false; if(!searchData(x)) return false; // there is a thing to delete BinTree<T>* btP = findParent(x); if(btP == root){ btP = btP->getRChild(); } else{ if(btP->getData()<x) btP = btP->getRChild(); else if(btP->getData()>x) btP = btP->getLChild(); } // this is the node to delete. // we will find the number that's barely smaller than btP's number. // only right child exists if(btP->getLChild()==NULL){ if(btP->getParent()->getLChild()==btP){ btP->getParent()->addLChild(btP->getRChild()); } else{ btP->getParent()->addRChild(btP->getRChild()); } delete btP; } else{ BinTree<T>* btS = btP->getLChild(); while(btS->getRChild()!=NULL){ btS = btS->getRChild(); } btP->setData(btS->getData()); if(btS->getParent()==btP) btP->addLChild(btS->getLChild()); else btS->getParent()->addRChild(btS->getLChild()); delete btS; } nodeCount--; return true; } void printInOrder(){ cout << "In Order: "; if(root->getRChild()!=NULL) root->getRChild()->printInOrderR(); cout << endl; } void printPreOrder(){ cout << "PreOrder: "; if(root->getRChild()!=NULL) root->getRChild()->printPreOrderR(); cout << endl; } void printPostOrder(){ cout << "Post Order: "; if(root->getRChild()!=NULL) root->getRChild()->printPostOrderR(); cout << endl; } void printLevelOrder(){ cout << "Level Order: "; if(root->getRChild()!=NULL) root->getRChild()->printLevelOrder(); cout << endl; } int numWaysToGetBST(int mod_num){ // TO DO } }; /* UPLOAD END */ void test1(){ BinarySearchTree<int> bst; bst.insertData(4); bst.insertData(2); bst.insertData(1); bst.insertData(3); bst.insertData(6); bst.insertData(5); bst.insertData(7); cout << bst.numWaysToGetBST(10007) << endl; //80 bst.insertData(10); bst.insertData(8); cout << bst.numWaysToGetBST(10007) << endl; //448 } int main(){ test1(); return 0; }
12-06
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值