People discuss shallow copy and deep copy in the context of classes.
Lets try to understand these two terms via examples. Consider the following two pieces of code.
Example 1
int b = 5; int a = b;
Example 2
int *b = new int; *b = 5; int* a = b;
C++ performs Shallow Copy by default. So in both these examples, the copy we see is shallow in nature. In Example 1, a is assigned the value of b. In this case, a and b are independent variables, i.e, modifying a will not affect b and vice-versa. This works perfectly fine when the variables are stack allocated. However in Example 2, both a and b, although independent pointers, point to the same heap memory location. Modifying one will affect the other. If the copy had been a deep copy instead, a new heap memory would have been allocated for a.
Shallow Copy is generally harmless. As programmers, we have complete control of the code we write. Therefore, we can allocate new heap memory as and when required when we perform copy of objects. But there are situations where we hand over this copy responsibility to the compiler. Class special member functions, Copy Constructor and Assignment Operator are great examples. Both these functions are automatically generated by the compiler if we do not define them manually and both of them perform shallow copy of member variables. This becomes an issue when we have heap allocated variables as class members. In such scenarios, writing our own custom Copy Constructor and overloading the Assignment Operator are our only solutions.
Please note that the built-in classes in the standard library have been designed with custom Copy Constructors and overloaded Assignment Operators to handle deep copy of the member variables. Hence when we perform a copy of their objects, they are generally independent of each other. Note that when we have a vector of pointers, it is a different story. For example, in the below example, although both the vectors are independent objects, the content they store are one and the same.
#include <iostream> | |
#include <vector> | |
using namespace std; | |
int main() { | |
int* a = new int; | |
int* b = new int; | |
*a = 5; | |
*b = 4; | |
vector<int*> array = { a,b }; | |
vector<int*> array2 = array; | |
*array2[0] = 9; | |
cout << *array[0]; | |
} |
Output:
9
Leave a Reply