I’ve been trying to come up with a copy constructor for a tree. I’ve found quite a few suggestions.
This one interested me.
class TreeNode
{
int ascii;
TreeNode* left;
TreeNode* right;
public:
TreeNode() { ascii = 0; left = right = 0; }
TreeNode* clone();
// ...
};
TreeNode* TreeNode::clone()
{
if (TreeNode* tmp = new TreeNode)
{
tmp->ascii = ascii;
if (left) tmp->left = left->clone();
if (right) tmp->right = right->clone();
return tmp;
}
return 0;
}
What does “if (TreeNode* tmp = new TreeNode) mean?
Other than that it looks alright. It just doesn’t work very well.
Any idea what’s wrong with it?
The example above came from this site.
Well, for starters it’s not a copy constructor – the copy constructors have a very well defined syntax in C++, so a proper copy constructor would have the prototype
TreeNode(TreeNode const &). Just to get the terminology right (and the compiler will still generate a copy constructor as it has no idea what theclone()function is supposed to do).The expression in the if statement will both allocate a new TreeNode object and purports to check that the allocation succeeded (by checking that the resulting pointer isn’t 0). Unfortunately that’s pre-standard C++ and modern C++ implementations that are standard conforming will throw a
std::bad_allocexception instead, so the test will mainly give the user a warm fuzzy feeling that something is being done about memory allocation failure, even if it isn’t.In order to make the code work as expected on a standard-compliant compiler, you’ll have to use nothrow new. From memory the line would read something like this:
All that said, unless TreeNode is part of an object hierarchy that relies on the presence of the
clone()function I would do away with it and implement a proper C++ constructor instead. That way, the compiler and you are on the same page when it comes to duplicating objects, plus other programmers will find it a little easier to follow your code.