Copy Constructor Deep Copy vs Shallow Copy 9142021

  • Slides: 26
Download presentation
Copy Constructor Deep Copy vs Shallow Copy 9/14/2021 IT 279 1

Copy Constructor Deep Copy vs Shallow Copy 9/14/2021 IT 279 1

The Big Three 1. Copy Constructor 2. Assignment operator = 3. Destructor If you

The Big Three 1. Copy Constructor 2. Assignment operator = 3. Destructor If you need one of them, you need all of them 9/14/2021 IT 279 2

Overload assignment = as a member function a = b = c = d

Overload assignment = as a member function a = b = c = d = e; class point { public: . . . point & operator = (const point & a); . . . private: function name double my_x; return type double my_y; . . . is the pointer }; this parameter list of the calling object C = (A = B) 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; } A’s my_x and my_y 9/14/2021 (A is the calling object) IT 279 3

If x is an pointer, use -> instead of. (dot operator) Using = and

If x is an pointer, use -> instead of. (dot operator) Using = and -> class point { public: . . . point & operator = (const point & a); . . . private: . . . }; point a, b(4, 5); . . . a = b; . . a = point(2, 3); // a = new point(1, 2); 9/14/2021 point *a, *b; a = new point(5, 6); b = new point; . . printp(*a); All = in this block are not the operator = defined in class point. a->distance(*b); a = b; IT 279 4

What can we do? C++’s way point a, b(4, 5); . . . a

What can we do? C++’s way point a, b(4, 5); . . . a = b; a = point(1, 2); point a, b(4, 5); . . . a = b; a = new point(1, 2); 9/14/2021 class point { public: . . . point & operator = (const point & a); . . . private: . . . }; point *a, *b; a = new point(5, 6); b = a; point *a, *b; b = new point(1, 2); a = new point(5, 6); *b = *a; a=b; point *a, *b; a = new point(5, 6); *b = *a; a = new point(5, 6); *b = point(1, 2); point *a, *b; a = new point(5, 6); b = new point(1, 2); *b = *a; IT 279 point *a, *b; b = new point(5, 6); *b = point(1, 2); 5

The destructor : to destroy an object printp string printp(point p) {. . .

The destructor : to destroy an object printp string printp(point p) {. . . } . . . int main() { point v(4, 5); . . cout << printp(v); . . . } Constructed by the constructor 4 my_y 5 . . 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 . . 9/14/2021 my_x Copied by the copy constructor v: my_x p: IT 279 6

Define a destructor class point { public: . . . point & operator =

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. 9/14/2021 IT 279 7

Dynamic arrays, resizable arrays a 5 p i int a[3]={5, 60, 700}; int *p,

Dynamic arrays, resizable arrays a 5 p i int a[3]={5, 60, 700}; int *p, i; 1 p = new int[3]; 4 60 700 5 0 2 for (i=0; i<3; i++) p[i] = i; 2 1 1 2 0 p = new int[i]; 1 for (i=0; i<4; i++) p[i] = i*i; 4 9 9/14/2021 3 IT 279 8 4

Delete Dynamic arrays a 5 p int a[3]={5, 60, 700}; int *p, i; 1

Delete Dynamic arrays a 5 p int a[3]={5, 60, 700}; int *p, i; 1 i 4 3 p = new int[4]; 0 0 1 1 for (i=0; i<3; i++) p[i] = i; delete [] p; 60 700 3 p = new int[3]; 2 1 4 2 4 9 for (i=0; i<4; i++) p[i] = i*i; 9/14/2021 IT 279 9

Shallow Copy class Stack {. . . private: int my_size; int *my_stk; // pointer

Shallow Copy class Stack {. . . private: int my_size; int *my_stk; // pointer to a dynomic array. . . }; Stack a my_size 4 Sha llow my_stk . . . Shallow copy can be done by default copy constructor Stack b Co my_size py 0 4 my_stk . . . 1 4 9 9/14/2021 IT 279 10

Deep Copy class Stack {. . . private: int my_size; int *my_stk; // pointer

Deep Copy class Stack {. . . private: int my_size; int *my_stk; // pointer to a dynomic array. . . }; Stack a Deep copy needs to program the copy constructor Stack b my_size 4 my_stk . . . 4 new int[4] . . . 0 0 1 4 9 9/14/2021 my_size IT 279 Deep Copy 1 4 9 11

Dynamic Arrays and The Big Three In general, if a dynamic array is used

Dynamic Arrays and The Big Three In general, if a dynamic array is used in the class, then its big three need deep copy. 1. Copy Constructor 2. Assignment operator = 3. Destructor Java doesn’t have the destructor 9/14/2021 IT 279 12

Stack Class class Stack // First in last out { public: Stack(); // default

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; }; 9/14/2021 IT 279 13

The Copy Constructor Stack: : Stack(const Stack & a) { my_size = a. my_size;

The Copy Constructor Stack: : Stack(const Stack & a) { 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]; } // 1. copy constructor; Stack b Stack a 4 my_head 3 0 my_size 4 my_tail my_head 3 stk my_tail 0 . . . stk 0 . . . 1 4 9 9/14/2021 my_size IT 279 Deep Copy new int[4] 0 1 4 9 14

Deep Copy for Assignment a = b b a my_size 4 my_stk . .

Deep Copy for Assignment a = b b a my_size 4 my_stk . . . 0 1 4 0 Deep Copy 9 9/14/2021 1 4 9 IT 279 15

Problem of Deep Copy for Assignment a = b b a my_size 4 3

Problem of Deep Copy for Assignment a = b b a my_size 4 3 my_size 3 my_stk . . . 0 1 4 wasted 9/14/2021 2 4 6 Deep Copy 2 4 6 9 IT 279 16

Problem of Deep Copy for Assignment a = b b a my_size 4 5

Problem of Deep Copy for Assignment a = b b a my_size 4 5 my_size 5 my_stk . . . This location belongs to someone else 9/14/2021 0 2 1 4 4 6 9 8 8 10 10 Deep Copy 2 4 6 IT 279 17

Operator = Stack & Stack: : operator=(const Stack & a) // 2. assignment operator;

Operator = Stack & Stack: : operator=(const Stack & a) // 2. assignment operator; { my_size = a. my_size; my_head = a. my_head; a = b 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; } We have problem! a my_size 4 3 b my_stk 0 wasted 9/14/2021 my_size 3 my_stk . . . 1 2 4 4 9 6 Deep Copy 2 4 6 IT 279 18

Solution for Assignment a = b b a my_size 4 5 new int[5] .

Solution for Assignment a = b b a my_size 4 5 new int[5] . . . delete 1 4 9 9/14/2021 5 my_stk 0 my_size 2 4 . . . Deep Copy 2 4 6 6 8 8 10 10 IT 279 19

Another Problem for Assignment Stack & Stack: : operator=(const Stack & a) // 2.

Another Problem for Assignment Stack & Stack: : operator=(const Stack & a) // 2. assignment operator; { my_size = a. my_size; my_head = a. my_head; my_tail = a. my_tail; delete stk[]; 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; } We still have problem! new int[4] a 0 delete 1 4 9 9/14/2021 my_size 4 x my_stk x . . . x a = a IT 279 Deep Copy x 20

Correctly overload = Stack & Stack: : operator=(const Stack & a) { if (my_size

Correctly overload = Stack & Stack: : operator=(const Stack & a) { if (my_size != a. my_size) { delete [] stk; stk = new int[a. my_size]; } // 2. assignment operator; my_size = a. my_size; my_head = a. my_head; my_tail = a. my_tail; for (int i =0; i<my_size; i++) stk[i] = a. stk[i]; return *this; // So, we can use a=b=c; } 9/14/2021 IT 279 21

Desctructor Stack: : ~Stack() { delete [] stk; } // 3. destructor Just delete

Desctructor Stack: : ~Stack() { delete [] stk; } // 3. destructor Just delete all dynamic arrays created in this class. 9/14/2021 IT 279 22

Inheritance and Big-Three // Base class A { public: A(int a); A(const A &

Inheritance and Big-Three // Base class A { public: A(int a); A(const A & a); //Copy constructor; A & operator = (const A & a); // overload = ~A(); // Destructor; . . . // Derived class private: class B : public A int size_A; { int *array_A; public: }; B(int b); B(const B & b); //Copy constructor; B & operator = (const B & b); // ~B(); // Destructor; In private section!!. . . private: Use A’s constructor int size_B; int *array_B; }; 9/14/2021 IT 279 23

Inheritance and copy Constructor // Derived class B : public A { public: B(int

Inheritance and copy Constructor // Derived 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]; } 9/14/2021 IT 279 24

Inheritance and assignment = // Derived class B : public A { X=Y public:

Inheritance and assignment = // Derived class B : public A { X=Y public: B(int b); B(const & B); //Copy constructor; B & operator = (const B & b); // ~B(); // Destructor; // Derived class. . . B & B: : operator = (const B & b) private: { int size_B; A: : operator=(b); int *array_B; }; if (size_B != b. size_B()) { delete [] array_B; array_B = new int[size_B]; }; This will take care of the variables in the base class for (int i =0; i<size_B; i++) array_B[i] = b. array_B[i]; return *this; } 9/14/2021 IT 279 25

Inheritance and destructor // Derived class B : public A { public: B(int b);

Inheritance and destructor // Derived 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; }; Mind your own business // Derived class B: : ~B() { delete [] array_B; } 9/14/2021 IT 279 26