I'm trying to learn "big three" in C++.. I managed to do very simple program for "big three".. but I'm not sure how to use the object pointer.. The following is my first attempt.
I have a doubt when I was writing this...
Questions
Am I correct in saying that I need to delete the pointer in destructor?
class TreeNode
{
public:
TreeNode();
TreeNode(const TreeNode& node);
TreeNode& operator= (const TreeNode& node);
~TreeNode();
private:
string data;
TreeNode* left;
TreeNode* right;
friend class MyAnotherClass;
};
Implementation
TreeNode::TreeNode(){
data = "";
}
TreeNode::TreeNode(const TreeNode& node){
data = node.data;
left = new TreeNode();
right = new TreeNode();
left = node.left;
right = node.right;
}
TreeNode& TreeNode::operator= (const TreeNode& node){
data = node.data;
left = node.left;
right = node.right;
return *this;
}
TreeNode::~TreeNode(){
delete left;
delete right;
}
Thanks in advance.
This is how I would do it:
Because you are managing two resources in the same object doing this correctly becomes a bit more complex (Which is why I recommend never managing more than one resource in an object). If you use the copy/swap idiom then the complexity is limited to the copy constructor (which is non trivial to get correct for the strong exception guarantee).
TreeNode::TreeNode()
:left(NULL)
,right(NULL)
{}
/*
* Use the copy and swap idium
* Note: The parameter is by value to auto generate the copy.
* The copy uses the copy constructor above where the complex code is.
* Then the swap means that we release this tree correctly.
*/
TreeNode& TreeNode::operator= (const TreeNode node)
{
std::swap(data, node.data);
std::swap(left, node.left);
std::swap(right, node.right);
return *this;
}
TreeNode::~TreeNode()
{
delete left;
delete right;
}
The hard part now:
/*
* The copy constructor is a bit harder than normal.
* This is because you want to provide the `Strong Exception Guarantee`
* If something goes wrong you definitely don't want the object to be
* in some indeterminate state.
*
* Simplified this a bit. Do the work that can generate an exception first.
* Once all this has been completed we can do the work that will not throw.
*/
TreeNode::TreeNode(const TreeNode& node)
{
// Do throwable work.
std::auto_ptr<TreeNode> nL(node.left == null ? null : new TreeNode(*node.left));
std::auto_ptr<TreeNode> nR(node.right == null ? null : new TreeNode(*node.right));
// All work that can throw has been completed.
// So now set the current node with the correct values.
data = node.data;
left = nL.release();
right = nR.release();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With