Copy constructors are constructors used to create a copy of an existing object; it takes one parameter that is of the same type as the class. When do we use such a thing?
Student a(b);
whenb
is an existing instance ofStudent
.Student a = b;
in the same line, where we create an objecta
and initialise it withb
. Note here that we’re not calling theoperator=
function.a=b
is where it’s called.- Pass an object by value (because we make a copy!).
- Return an object by value.
By default, a non-empty copy constructor is implemented in every class by the compiler; it does a shallow copy of all fields. If we were to implement it ourselves, we must pass the object by reference or we get a compile-time error. If we pass by value, then the copy constructor will recursively call itself infinitely many times. Like other constructors, it has no return
statement.
Pointers
The default copy constructor does a shallow copy, i.e., it will copy a pointer from object A to object B, but not dynamically allocate new space.
We run into a problem: what happens when data members are pointers? In this case, having two independent objects point to the same string (for example) in memory can cause problems. If the string of one changes, then the other will change too, so they’re not independent objects. So we need to work around this by implementing our own copy constructor that doesn’t do a shallow copy.
The below has a fix. We dynamically allocate a new string for the new object. That wasn’t complicated at all!
We pass by reference because if we pass by value, we copy in a copy of the input, so we’d have to call the copy constructor again. The compiler spits out an error if we don’t do so.