shallow copy vs deep copy

A shallow copy of an object copies all of the member field values. This works well if the fields are values, but may not be what you want for fields that point to dynamically allocated memory. The pointer will be copied. but the memory it points to will not be copied -- the field in both the original object and the copy will then point to the same dynamically allocated memory, which is not usually what you want. The default copy constructor and assignment operator make shallow copies.

A deep copy copies all fields, and makes copies of dynamically allocated memory pointed to by the fields. To make a deep copy, you must write a copy constructor or overload the assignment operator.


If an object has pointers to dynamically allocated memory, and the dynamically allocated memory needs to be copied when the original object is copied, then a deep copy is required.


Example:
class A
{
int i;
public:
A()
{
i=0;
}
void Set()
{
i=20;
}
void display()
{

cout < <>

}

int main()
{
A a,b;
a.Set();//change i to 20
b=a;
b.display(); //this displays the value of i as 20
}
by default here the compiler generates the assignment operator for these objects.

object 'a' is copied into object 'b' . so object 'b' data member 'i' value will same as object 'a' data member 'i' value.

so the output of this program is 20. becoz object 'a' has changed the value of 'i' data member to 20.

what happens if the class A has a pointer *ptr whose memory is created dynamically.

class A

{

char *ptr;

public: A()

{

ptr=NULL;

}

void Set()

{
ptr=new char[5];
strcpy(ptr,"hai");

}

void display()
{
cout < <>

}

void erase()

{

delete []ptr;

}
};

int main()
{

A a;
a.Set();//change i to 20
A b;
b=a;
a.erase();
b.display(); //nothin will be displayed as the memory is erased by a;
system("pause");
return 0;

}

then if we copy object 'a' into object 'b'. pointer(ptr) of object 'a' will get copied to object 'b's ptr but not the value pointed by pointer ptr of object 'a'.

object 'b' s ptr and object 'a's ptr will be pointing to same memory. suppose if object 'a' deletes the its pointer, then the object 'b' will be pointing to the memory which is deleted by 'a' object, so object 'b's ptr will be dangling. I

n this case we go for deep copy. so whenever class has data members which are allocated memory dynamically then we should go for deep copy. deep copy copies the values pointed by pointers but not the pointers.

A class that requires deep copies will generally need:

i )a destructor to delete the dynamically allocated memory.
ii) a copy constructor to make a copy of the dynamically allocated memory.
iii) an overloaded assignment operator to make a copy of the dynamically allocated memory.

Example using the overloaded assignment operator

class A
{
char *ptr;
public: A()
{
ptr=NULL;
}
void Set()
{

ptr=new char[5];

strcpy(ptr,"hai");
}

void display()
{

cout < < ptr;

}
void operator = (const A& a)
{

if(this != &a)
{
ptr=new char[5];

strcpy(ptr,a.ptr);
}
}
void erase()
{
delete []ptr;
}
};
int main()
{
A a;
a.Set();
A b;
b=a;

//invokes overloaded = operator , so creates new memory for b.ptr instead of pointing to //same memory of a.ptr

a.erase();


b.display(); //this displays "hai" becoz memory is not destroyed

system("pause");
return 0;
}
Prev page



No comments: