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