Working on implementing my own BST in C++ for the experience of dealing with such structures.
I\'ve had trouble implementing a destructor. I found in my studies, that on
You can have a recursive destructor; what you can't do is delete the same object twice.
A typical way to delete a tree in C++ might be something like this:
BinSearchTree::~BinSearchTree()
{
delete _rootNode; // will recursively delete all nodes below it as well
}
tNode::~tNode()
{
delete left;
delete right;
}
Regarding the unresolved external error -- is that error thrown when you try to compile/link the program? If so, it's probably because the code for the tNode class (and in particular the tNode destructor, if you declared one) doesn't exist or isn't getting compiled into your project.
Previous answers have pointed out that the unresolved external error is likely caused by a tNode destructor that is declared but not defined in a translation unit that the linker can see.
However, you have a second error: You appear to believe that setting n to null does something it doesn't do. The pointer value n is passed by value, not by reference, such that changing its value (e.g. by assigning NULL) has no effect after the function returns.
This will probably give you errors when you clear the tree and expect the root node pointer to have been set to NULL, when it remains a dangling pointer to freed memory. The result will be runtime error, not your linker error.
void BinSearchTree::Clear(tNode **N)
{
tNode * n = *N;
if (n->left != NULL)
Clear(n->left);
if (n->right != NULL)
Clear(n->right);
delete n;
*N = NULL;
size--;
}
Will do what you expect.
Just use a destructors. It sounds like your problem is that you were trying to call the destructors directly, but the language handles this for you. They're called either when you leave a stack allocated object's scope, or when you delete an object.
All you should need is this:
~BinSearchTree() {
delete left;
delete right;
}
delete
will call their destructors.
Note: It's perfectly safe to delete NULL
, it has no effect.
You can also use recursion, you just need to change the function header to:
void remove(node*& root)
and it will work.
How about automating it:
class BinSearchTree
{
std::auto_ptr<tNode> left;
std::auto_ptr<tNode> right;
BinSearchTree(BinSearchTree const&);
BinSearchTree& operator=(BinSearchTree const&); // private
};
Now destruction is automatic. :-)
The problem is that in you class you probably declared that the node structure has a custom destructor, but you don't provide it so at link time the compiler is complaining a piece is missing.
If you don't need any more custom code in the destructor then you can just remove the destructor from the struct declaration and your program will compile fine.
Note however that there is no problem at all to have a destructor of to destory children nodes (see Brendan Long answer). If you ran into problems while attempting that the issue you faced must me something else.