A copy constructor is a constructor that takes an object of the same type as an argument. It is invoked whenever you initialize an object with the value of another. It can be invoked with the = sign, as in the example above, or with function-call syntax. For example, the initialization in the example above could be rewritten with the following syntax:
String yourString( myString );
This follows the traditional syntax for calling a constructor.
The way the String class is currently written, the compiler executes the above statement by initializing each member of yourString with the values of the members of myString. Just as with the default behavior during assignment, this is generally undesirable when the class contains pointers as members. The result of the above initialization is to give both yourString and myString the same character buffer, which can cause errors when the objects are destroyed by the destructor.
The solution is to write your own copy constructor. The copy constructor for the String class can be written as follows:
#include <iostream.h>
#include <string.h>
// ------- string class
class String
{
public:
String();
String( const char *s );
String( char c, int n );
String( const String &other ); // Copy constructor
// etc...
};
// ----------- Copy constructor
String::String( const String &other )
{
length = other.length;
buf = new char[length + 1];
strcpy( buf, other.buf );
}
The implementation of the copy constructor is similar to that of the assignment operator in that it allocates a new character buffer for the object being created. Note that the copy constructor actually takes a reference to an object, instead of an object itself, as a parameter.
In general, there are only a few differences between copy constructors and assignment operators:
An assignment operator acts on an existing object, while a copy constructor creates a new one. As a result, an assignment operator may have to delete the memory originally allocated for the receiving object.
An assignment operator must check against self-assignment. The copy constructor doesn't have to, because self-initialization is impossible.
To permit chained assignments, an assignment operator must return *this. Because it is a constructor, a copy constructor has no return value.