Let's go through this.
As you can tell from the name, that's a constructor. Because it takes a parameter a reference to an object of the same type, it's a copy constructor (C++ nomenclature).
As you know (or not), if you don't have a copy constructor, the compiler will generate one for you. The compiler generated copy constructor does a shallow copy.
Why you want to implement your own:
class Car {
char *LicencePlate;
public:
Car(char* plate, int size)
{
LicencePlate = new char[size];
strcpy(LicencePlate, plate);
}
~Car()
{
delete[] LicencePlate;
}
};
I've modified your class a bit to better explain. Your class manages memory now. It allocates memory for LicencePlate
. This is the scenario where you don't have a copy constructor. Say you do:
Car a("abc",3);
The compiler generated copy constructor is called with:
Car b(a);
But remember, this only does a shallow copy. So, actually, a.LicencePlate == b.LicencePlate
. Can you see anything wrong with that?
When a
goes out of scope, the destructor is called, and a.LicencePlate
is deleted. But then you run into undefined behavior when b
goes out of scope, because b
's destructor will try to delete the same memory (remember, the two pointer point to the same memory because a shallow copy was created).
To avoid this, you define your own copy constructor:
class Car {
char *LicencePlate;
int sz;
public:
Car(char* plate, int size)
{
LicencePlate = new char[size+1]();
strcpy(LicencePlate, plate);
sz = size;
}
Car(const Car& other)
{
LicencePlate = new char[other.sz+1]();
sz = other.sz;
strcpy(LicencePlate, other.LicencePlate);
}
~Car()
{
delete[] LicencePlate;
}
};
The rule of three means you should implement an assignment operator (you already have a copy constructor and a destructor). The motivation behind this is the same, only the problem replicates when you assign instead of initialize:
Car a("abc",3);
Car b;
b = a; //assignment - operator= is called
Now we're safe. b
, when copied, will allocate new memory to hold the licence plate, so the double-delete can't occur.
I changed the code to demonstrate the point but you'll still have to put logic in there yourself.