1 Overload assignment = as a member function class point { public:..... point & operator = (const point & a);..... private: double my_x; double my_y;..... }; point & point::operator = (const point & a) { my_x = a.my_x; my_y = a.my_y; return *this; // return as this so we can use a=b=c; } this is the pointer of the calling object C = (A = B) A ’s my_x and my_y
2 Using = and -> class point { public:..... point & operator = (const point & a);..... private:..... }; point a,b;..... a = b;.... a = point(2,3); point *a, *b; a = new point(5,6); b = new point;.... printp(*a); a -> distance(*b);
3 The Big Three 1.Copy Constructor 2.Assignment operator = 3.Destructor If you need one of them, you need all of them
4 The destructor : to destroy an object string printp(point p) { } int main() { point v;.... cout << printp(v);..... } 4 5 my_x my_y..... v: 4 5 my_x my_y..... p: printp.... When printp(v) in the main function is done, the copy of v must be destroyed. the destructor of point will be called to do the job Constructed by constructor Constructed by copy constructor
5 Define a destructor class point { public:..... point & operator = (const point & a); // assignment operator point(const point & a); // copy constructor ~point(); // destructor..... private: double my_x; double my_y;..... };.... point::~point() // nothing to be done; {} In fact, class point doesn’t need to explicitly program the big three; namely, the default ones can do the job.
6 Dynamic arrays, resizable arrays int a[3]={5,60,700}; int *p,i; p = new int[3]; for (i=0; i<3; i++) p[i] = i; p = new int[4]; for (i=0; i<4; i++) p[i] = i*i; 4 apiapi
7 Delete Dynamic arrays int a[3]={5,60,700}; int *p,i; p = new int[3]; for (i=0; i<3; i++) p[i] = i; delete [] p; p = new int[4]; for (i=0; i<4; i++) p[i] = i*i; 4 apiapi
8 Shallow Copy class Stack {..... private: int my_size; int *my_stk; // pointer to a dynomic array..... }; 4 my_size my_stk Stack aStack b 4 my_size my_stk Shallow Copy Shall copy can be done by default copy constructor
9 Deep Copy class Stack {..... private: int my_size; int *my_stk; // pointer to a dynomic array..... }; 4 my_size my_stk Stack a Stack b 4 my_size my_stk Deep copy needs to program the copy constructor new int[4] Deep Copy
10 Dynamic Arrays and The Big Three 1.Copy Constructor 2.Assignment operator = 3.Destructor In general, if a dynamic array is used in the class, then its big three need deep copy.
11 Stack Class class Stack // First in last out { public: Stack(); // default constructor Stack(int *a, int n); // construct and push array a into the stack int pop(); // pop out the top element int push(int a); // push a into the stack int size(); // return the size of the stack; // The following three are so-called the Big Three; // They need to handle the dynamic array *my_size; Stack(const Stack & a); // 1. copy constructor; Stack & operator=(const Stack & a); // 2. assignment operator; ~Stack(); // 3. destructor; private: int *stk; int my_size; int head, tail; };
12 The Big Three of Class Stack Stack::Stack(const Stack & a) // 1. copy constructor; { my_size = a.my_size; my_head = a.my_head; my_tail = a.my_tail; stk = new int[my_size]; for (int i =0; i<my_size; i++) stk[i] = a.stk[i]; } Stack & Stack::operator=(const Stack & a) // 2. assignment operator; { my_size = a.my_size; my_head = a.my_head; my_tail = a.my_tail; stk = new int[my_size]; for (int i =0; i<my_size; i++) stk[i] = a.stk[i]; return *this; // So, we can use a=b=c; } Stack::~Stack() // 3. destructor { delete [] stk; } We have problem!
13 Deep Copy for Assignment a = b 4 my_size my_stk a b 4 my_size my_stk Deep Copy
14 Problem of Deep Copy for Assignment a = b 4 my_size my_stk a b 3 my_size my_stk Deep Copy wasted
15 Problem of Deep Copy for Assignment a = b 4 my_size my_stk a b 5 my_size my_stk Deep Copy This location belongs to someone else
16 Solution for Assignment a = b 4 my_size my_stk a b 5 my_size my_stk Deep Copy 5 delete new int[5]
17 Another Problem for Assignment a = a 4 my_size my_stk a x x x x delete new int[5]
18 Correctly overload = Stack & Stack::operator=(const Stack & a) // 2. assignment operator; { if (my_size != a.my_size) { delete [] stk; stk = new int[a.my_size]; } my_size = a.my_size; my_head = a.my_head; my_tail = a.my_tail; stk = new int[my_size]; for (int i =0; i<my_size; i++) stk[i] = a.stk[i]; return *this; // So, we can use a=b=c; }
19 Inheritance and Big-Three // Base class class A { public: A(int a); A(const A & a); //Copy constructor; A & operator = (const A & a); // overload = ~A(); // Destructor;..... private: int size_A; int *array_A; }; // Derived class class B : public A { public: B(int b); B(const B & b); //Copy constructor; B & operator = (const B & b); // ~B(); // Destructor;..... private: int size_B; int *array_B; }; In private section!! Use A’s constructor
20 Inheritance and copy Constructor // Derived class class B : public A { public: B(int b); B(const B & b); //Copy constructor; B & operator = (const B & b); // ~B(); // Destructor;..... private: int size_B; int *array_B; }; // Derived class B::B(const B & b) :A(b) // call the copy constructor of A; { size_B = b.size_B; array_B = new int[size_B]; for (int i=0; i<size_B; i++) array_B[i] = b. array_B[i]; }
21 Inheritance and assignment = // Derived class class B : public A { public: B(int b); B(const & B); //Copy constructor; B & operator = (const B & b); // ~B(); // Destructor;..... private: int size_B; int *array_B; }; // Derived class B & B::operator = (const B & b) { A::operator=(b); if (size_B != b.size_B()) { delete [] array_B; array_B = new int[size_B]; }; for (int i =0; i<size_B; i++) array_B[i] = b.array_B[i]; return *this; } This will take care of the variables in the base class
22 Inheritance and destructor // Derived class class B : public A { public: B(int b); B(const & B); //Copy constructor; B & operator = (const B & b); // ~B(); // Destructor;..... private: int size_B; int *array_B; }; // Derived class B::~B() { delete [] array_B; }