class person{char* name;int age;
public:
// the constructor acquires a resource:// in this case, dynamic memory obtained via new[]person(const char* the_name, int the_age){name = new char[strlen(the_name) + 1];strcpy(name, the_name);age = the_age;}
// the destructor must release this resource via delete[]~person(){delete[] name;}};
// 1. copy constructorperson(const person& that){name = new char[strlen(that.name) + 1];strcpy(name, that.name);age = that.age;}
// 2. copy assignment operatorperson& operator=(const person& that){if (this != &that){delete[] name;// This is a dangerous point in the flow of execution!// We have temporarily invalidated the class invariants,// and the next statement might throw an exception,// leaving the object in an invalid state :(name = new char[strlen(that.name) + 1];strcpy(name, that.name);age = that.age;}return *this;}
// 2. copy assignment operatorperson& operator=(const person& that){char* local_name = new char[strlen(that.name) + 1];// If the above statement throws,// the object is still in the same state as before.// None of the following statements will throw an exception :)strcpy(local_name, that.name);delete[] name;name = local_name;age = that.age;return *this;}
class Car //A very simple class just to demonstrate what these definitions mean.//It's pseudocode C++/Javaish, I assume strings do not need to be allocated.{private String sPrintColor;private String sModel;private String sMake;
public changePaint(String newColor){this.sPrintColor = newColor;}
public Car(String model, String make, String color) //Constructor{this.sPrintColor = color;this.sModel = model;this.sMake = make;}
public ~Car() //Destructor{//Because we did not create any custom types, we aren't adding more code.//Anytime your object goes out of scope / program collects garbage / etc. this guy gets called + all other related destructors.//Since we did not use anything but strings, we have nothing additional to handle.//The assumption is being made that the 3 strings will be handled by string's destructor and that it is being called automatically--if this were not the case you would need to do it here.}
public Car(const Car &other) // Copy Constructor{this.sPrintColor = other.sPrintColor;this.sModel = other.sModel;this.sMake = other.sMake;}public Car &operator =(const Car &other) // Assignment Operator{if(this != &other){this.sPrintColor = other.sPrintColor;this.sModel = other.sModel;this.sMake = other.sMake;}return *this;}
}
Car car1 = new Car("mustang", "ford", "red");Car car2 = car1; //Call the copy constructorcar2.changePaint("green");//car2 is now green but car1 is still red.
//Shallow copy example//Assume we're in C++ because it's standard behavior is to shallow copy objects if you do not have a constructor written for an operation.//Now let's assume I do not have any code for the assignment or copy operations like I do above...with those now gone, C++ will use the default.
Car car1 = new Car("ford", "mustang", "red");Car car2 = car1;car2.changePaint("green");//car1 is also now greendelete car2;/*I get rid of my car which is also really your car...I told C++ to resolvethe address of where car2 exists and delete the memory...which is alsothe memory associated with your car.*/car1.changePaint("red");/*program will likely crash because this area isno longer allocated to the program.*/