現在、データ構造クラス用のテンプレート化されたバイナリ検索ツリーをC++で開発しています。これまですべてが順調に進んでいます。この問題は、私がよく知らないいくつかの本質的なC ++のものを扱っており、助けが必要です。
ツリーをトラバースし、各ノードに異なる順序でアクセスする関数を以前に定義しました。ここで問題となっているのは次のように定義されています。
TreeNode.h
public:
static void PostOrderVisit(TreeNode<T>* node, void visit(const T& v));
TreeNode.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()メソッドはどちらも同じクラス内にあります。
前もって感謝します。