I'm trying to implement a Binary Search Tree using smart pointers and I've read that the recommended way to implement it is by using unique_ptr since a parent owns the child and there are no multiple owners in a binary search tree.
Take this tree for example,
10
4 20
2 5 11 30
3
here 4 is left child of 10 and 2 is left child of 4 and 3 is right child of 2 and so on.
Now the struct looks like,
template<typename T>
struct TreeNode {
T data;
std::unique_ptr<TreeNode<T>> left, right;
};
there's a unique_ptr<TreeNode<T>> root
pointing to the root.
Now if I'm understanding it correctly unique_ptr's
can't be copied or assigned and they have unique ownership of the object.
So if I want to traverse the tree I can't do something like initialize a std::unique_ptr<TreeNode<T>> temp
to the root and traverse every node from there since it'll throw an error once I try to set the root
which is a unique_ptr
to the temp
.
So do I need to use a raw pointer of type TreeNode*
to traverse the tree and perform operations? is it good or safe to do so? For all my operations on this tree then will I have to use raw pointers?
Another problem is with deleting a node. If I say want to delete node with the value 3
. If I initialize a raw pointer of type TreeNode* temp
and arrive at Treenode 3
. Then if I call delete(temp) what will happen? A unique_ptr
from TreeNode 2
is pointing at TreeNode 3
. What will happen to this pointer?
CodePudding user response:
Then if I call delete(temp) what will happen?
The TreeNode
will be destroyed. Note that delete
doesn't need parentheses
A
unique_ptr
fromTreeNode
2 is pointing atTreeNode
3. What will happen to this pointer?
The pointer becomes invalid, and it is undefined behaviour for the unique_ptr
object to be destroyed, as it will attempt to delete
an invalid pointer.
So do I need to use a raw pointer of type TreeNode* to traverse the tree and perform operations? is it good or safe to do so? For all my operations on this tree then will I have to use raw pointers?
You can have a reference (or pointer) to a std::unique_ptr
, you don't need to copy it.
Rather than delete
a raw pointer, you can call the reset
member function of the unique_ptr
to free the pointed-to TreeNode