我现在正在用 C++ 为数据结构类开发一个模板化的二叉搜索树。到目前为止,一切都进展顺利。这个问题涉及一些我不熟悉的细节 C++ 东西,我需要帮助。
我之前定义了遍历树并以不同顺序访问每个节点的函数。这里所讨论的定义如下。
树节点.h
public:
static void PostOrderVisit(TreeNode<T>* node, void visit(const T& v));
树节点.cpp
template <class T> void TreeNode<T>::PostOrderVisit(TreeNode* node, void visit(const T& v)) {
if (node->leftChild != NULL)
PostOrderVisit(node->leftChild, visit);
if (node->rightChild != NULL)
PostOrderVisit(node->rightChild, visit);
visit(node->value);
}
这在制作节点并静态调用 PostOrderVisit 的测试程序中运行良好。
在一个朋友类(BinSTree.h/cpp)中,我正在实现一个删除树中每个节点的方法,所以我认为使用这个访问者并在每个节点上调用我的 Delete() 函数是个好主意( Delete() 函数在 BinSTree 的测试程序中也可以正常工作)。
该函数定义如下。
template <class T> void BinSTree<T>::ClearTree() {
TreeNode<T>::PostOrderVisit(this->root(), &BinSTree<T>::Delete);
}
这就是问题所在。g++ 说……
BinSTree.cpp:156: error: no matching function for call to ‘TreeNode<int>::PostOrderVisit(TreeNode<int>*, void (BinSTree<int>::*)(const int&))’
TreeNode.cpp:56: note: candidates are: static void TreeNode<T>::PostOrderVisit(TreeNode<T>*, void (*)(const T&)) [with T = int]
在这种情况下,我认为那void (BinSTree<T>::*)(const T&)
将是 的一个实例void (*)(const T&)
,但事实并非如此。我可以让函数定义识别调用的唯一方法是像这样转换函数指针:
TreeNode<T>::PostOrderVisit(this->root(), (void (*)(const T& v)) &BinSTree<T>::Delete);
这可以识别函数并适当地调用它,但是(这需要进行一些重要的研究......),C++ 成员函数有一个隐式参数,允许从内部访问“this”关键字。将成员函数指针转换为普通函数指针会完全删除“this”引用,导致我的 Delete() 方法出现段错误(它使用了很多“this”)。
这太麻烦了,我花了很多时间在这个项目的一小部分上。谁能告诉我一种方法:A:在没有强制转换的情况下识别函数,或者 B:如何在整个强制转换中保持“this”引用。ClearTree() 和 Delete() 方法都在同一个类中。
提前致谢。