title: Binary Tree Copy Constructor
body: <p>I have a school assignment which requires me to create a binary tree in c++, complete with all the usual overloaded operators (=, ==, !=, copy, destroy, etc).  I am currently struggling to program the copy constructor method.  In this assignment, I am being asked NOT to use the binary tree class' insert method in either the operator= or copy constructor methods.  Here's the binary tree class header file:</p>
  
  <pre><code>#ifndef BINTREE_H
  #define BINTREE_H
  #include &lt;iostream&gt;
  #include "nodedata.h"
  using namespace std;
  
  class BinTree
  {
  
  public:
      BinTree();                           // constructor
      BinTree(const BinTree &amp;);            // copy constructor, calls copyHelper
      ~BinTree();                          // destructor, calls makeEmpty
      bool insert(NodeData*);              // insert method, inserts new nodes
      bool isEmpty() const;                // true if tree is empty, otherwise false
  
  private:
      struct Node
      {
          NodeData* data;              // pointer to data object
          Node* left;                  // left subtree pointer
          Node* right;                 // right subtree pointer
      };
      Node* root;                          // root of the tree
      Node&amp; copyHelper(const Node*);       // copies the tree recursively
      void makeEmpty(Node*);               // deletes nodes recursively
  };
  
  #endif
  </code></pre>
  
  <p>And here's what I've got so far for the copy constructor:</p>
  
  <pre><code>BinTree::BinTree(const BinTree &amp;otherTree)
  {
      root = copyHelper(otherTree.root); // 1
  }
  
  Node&amp; BinTree::copyHelper(const Node* other) // 2
  {
      if(other == NULL)
      {
          return NULL; // 3
      }
      Node newNode; // 4
      if(other.data == NULL)
      {
          newNode.data = NULL; // 5
      }
      else
      {
          NodeData newNodeData(*other-&gt;data); // 6
          newNode.data = newNodeData; // 7
      }
      newNode.left = copyHelper(other.left); // 8
      newNode.right = copyHelper(other.right); // 9
      return newNode; // 10
  }
  </code></pre>
  
  <p>This is causing all manner of compile errors, and I don't understand any of them.  Here's what I THINK should be happening:
  •Overview:  The entire tree will be copied from the ground up recursively.  Each node should already contain data and links to all subsidiary nodes (if they exist) when it is returned to the node above it.</p>
  
  <ol>
  <li>Since root is, by definition, a pointer to a Node object, there should be no issue with assigning it to a function which returns a Node object.  However, the compiler is giving me a conversion error here.</li>
  <li>The copyHelper function, which is called recursively, takes a pointer to one of the original nodes as an argument, and returns a copy of this node.</li>
  <li>If there is no original node, then there's no point in building a copy of it, so a NULL value is returned.</li>
  <li>newNode will eventually become a copy of "other".</li>
  <li>If "other" does not have any NodeData linked to it, then newNode's data pointer will link to NULL instead.</li>
  <li>Otherwise, a new NodeData called "newNodeData" will be created, using the NodeData copy constructor, which is called by dereferencing other's NodeData pointer.</li>
  <li>newNode's data pointer now points to newNodeData, which now contains the same string as other's NodeData object.</li>
  <li>newNode's left pointer will point to another node, which is created recursively by calling copyHelper on whatever Node other's left pointer is assigned to.</li>
  <li>newNode's right pointer will point to another node, which is created recursively by calling copyHelper on whatever Node other's right pointer is assigned to.</li>
  <li>Only once this node and all the nodes beneath it have been copied and returned to it will it be returned itself.</li>
  </ol>
  
  <p>Here are my existing questions:</p>
  
  <ul>
  <li>I'm assuming that we only need to use -> instead of . when we're dereferencing a pointer.  Is this correct?</li>
  <li>I know sometimes we need to use the "new" statement when creating objects (see part 4), but I've typically only seen this done when creating pointers to objects.  When, specifically are we supposed to be using the "new" statement?</li>
  <li>If I were to create newNode as a pointer (IE: Node* newNode = new Node;), wouldn't this cause a pointer to a pointer when it was returned?  Wouldn't that be less efficient than simply having the first pointer point directly to the returned Node object?  Is there some technical reason I can't do it this way?</li>
  <li>When is it advisable to take a pointer by reference as a parameter, instead of simply taking the pointer, or even the object itself?  Is this relevant here?</li>
  <li>The compiler seems to think I'm declaring a Node named BinTree::copyHelper instead of defining a function that returns a Node.  How can I prevent this?</li>
  </ul>
  
  <p>In general, I think I have the concepts down, but the syntax is completely killing me.  I literally spent all day yesterday on this, and I'm ready to admit defeat and ask for help.  What mistakes do you guys see in my code here, and how can I fix them?</p>