It turns out that there are two types of constructors the compiler can generate
This default constructor will call each data member’s default constructor in order to initialize the object. If the programmer wishes to override that default constructor, he or she simply provides one.
There is another type of constructor which the compiler generates — it is called a copy
constructor, and it's called whenever an object needs to be constructed from an existing
one. Suppose we had a class to encapsulate strings, and we call this class MyString1 . It
might include such data members as the length of the string as well as the characters
which would be in the string.
MyString(const char* s = "");
For this example, we’ll assume that the MyString constructor will allocate space for the
characters, and the destructor will free that space.
The copy constructor may be called when doing simple initializations of a MyString
MyString clone = me; // copy constructor gets called.
More importantly, the copy constructor is called when passing an object by value, or
returning an object by value. For instance, we might have a function which opens a file:
void OpenFile(MyString filename)
// Convert the object to a character string, open a stream...
We might declare a string and call the OpenFile function like this:
When passing the name object, the copy constructor is called to copy the MyString object
from the calling function to the local parameter in the OpenFile function. Because we did
not specify a copy constructor, the default copy constructor is called.
Default Copy Constructor
The default copy constructor does a member-wise copy of an object. For our MyString
class, the default copy constructor will copy the length integer and the characters
pointer. However, the characters themselves are not copied. This is called a shallow
copy, because it only copies the data one level deep in a class hierarchy. In memory,
what we’d have would look like this: