Copy constructors are called by the compiler when constructing an object by copying another object.
Using the following class:
class Square {
public:
Square(int side, std::string colour) : m_side {side}, m_colour {&colour} {}
// Getters and setters here
int area() const {
return m_side*m_side;
}
private:
int m_side;
std::string *m_colour;
};
Copy constructors are called when passing an object to a function as a copy and we can take a copy with the following code.
Square s1;
Square s2 {s1};
C++ generates a default copy constructor for you but, this performs a member-wise copy of source class, copying one member at a time. It will also copy the address of the pointer, causing both objects to point to the same bit bit of memory. Changing the age in s2 will also change the age in s1.
To fix this we can create our own copy constructor that handles the pointer correctly:
Square::Square(const Square &source): side {source.side}, colour {new std::string(*(source.get_colour())))) {}
This does a deep copy as opposed to a shallow copy. Deep copies can get complex and computationally expensive.
Copy constructors can delegate to to a normal constructors also.