Tuesday, June 3, 2008

Deep copy and shallow copy

If an object contains dynamically allocated data members then Shallow copy just copies the pointers of these. So the copied object and original object point to the same value.
Deep copy will allocate memory for these members then copy the contents not the pointers.
Point to note here is Compiler provided assignment operator as well as copy constructor will perform shallow copy.
This article clearly explains the difference between deep and shallow copying of objects.

http://www.fredosaurus.com/notes-cpp/oop-condestructors/shallowdeepcopy.html



Now for an example

#include

using std::cin;

using std::cout;

using std::endl;
//class definition

class deep

{

public:

int *m;//this has to be dynamically allocated

void print();

};


void deep::print()

{

cout<<"The number is "<<*m<< endl;<>
}


int main()

{
//create two objects of deep class

deep d1,d2;

d1.m = new int;

*(d1.m)=15;
//copy to d2

d2=d1;
//print d1 and d2;

cout<<"D1 is ";

d1.print();
cout lt<"D2 is ";

d2.print();
//Now change d2

*(d2.m)=75;
//again print d1 and d2

cout <<"After modifying d2 ======\n";

cout<<"D1 is \n";

d1.print();
cout<<"D2 is \n";

d2.print();
return 0; //successful termination of the program

}



And here is the output of the program

D1 is

The number is 15

D2 is

The number is 15

After modifying d2 ======

D1 is

The number is 75

D2 is

The number is 75

Press any key to continue



As you can see, modifying d2 modifies d1 as well because d1.m and d2.m are pointing at the same integer. This is shallow copy

Here you should not the point that compiler provided assignment operator does shallow copying.


Now let us provide deep copying.
class deep
{
public:
int *m;//this has to be dynamically allocated
void print();
deep& operator =(deep& d1);
~deep();
deep();
};
deep::deep()
{
m = new int;
}
deep::~deep()//destructor
{
delete m;
}
void deep::print()
{
cout<<"The number is "<<*m<<endl;
}
//assignment operator for deep copy
deep& deep::operator =(deep& d1)
{
if (&d1== this)//check for self assignment
return *this;
else
{
delete m;
m = new int;
*m = *(d1.m);
}
return *this;
}
int main()
{
//create two objects of deep class
deep d1,d2;
*(d1.m)=15;
//copy to d2
d2=d1;
//print d1 and d2;
cout<<"D1 is ";
d1.print();
cout<<"D2 is ";
d2.print();
//Now change d2
*(d2.m)=75;
//again print d1 and d2
cout<<"After modifying d2 ======\n";
cout<<"D1 is \n";
d1.print();
cout<<"D2 is \n";
d2.print();
return 0;//successful termination of the program
}
Look at the overloaded assignment operator. This will newly allocate memory for m after releasing the previous allocation and then copy the content of d1.m . if statement is meant for checking self assignment which could be hazardous.
The output of the program is
D1 is
The number is 15
D2 is
The number is 15
After modifying d2 ======
D1 isThe number is 15
D2 is
The number is 75
Press any key to continue

No comments: