Software & Finance





C++ - Shallow and Deep Copy





Shallow copy is used when there are no pointers variable. Deep copy is used when there is a pointer variable. Note we can use shallow copy, if we are using smart pointers which has got referece count. Smart Pointers are efficient way for memory management.

When there is a pointer member variable, just assigning the pointer variable from one class member to another class member is called shallow copy. So the pointer member variable in both classes will point to the same memory location.

When there is a pointer variable, just assigning the pointer variable from one class member to another class member is called shallow copy.

In the following sample code, I have used deep copy in assignment operator and shallow copy in copy constructor. When we use copy constructor in main function for the object str2, the program crashes at the time of exit as we have used shallow copy for pointer object, both objects str1.pMyString and str2.pMyString will point to the same location.

MyString str1("Welcome");
MyString str2 = str1; // calling copy constructor using shallow copy


When use assignment operator for the object str2, the program would work fine.
MyString str1("Welcome");
MyString str2;
str2 = str1; // calling assignment operator using deep copy

The correct implementation would be using deep copy for copy constructor.


Source Code


class MyString

{

private:

    char *m_pString;

 

public:

    MyString()

    {

        std::cout << "Calling Default Constructor\n";

        m_pString = NULL;

    }

 

    ~MyString()

    {

        if( this->m_pString != NULL)

        {

            std::cout << "Calling Destructor\n"; delete this->m_pString;

            this->m_pString = NULL;

        }

    }

 

    MyString(const char *p)

    {

        std::cout << "Calling Parameterized Constructor\n";

        int len = strlen(p);

        m_pString = new char [len + 1];

        strcpy(m_pString, p);

    }

 

    MyString(const MyString &other)

    {

        std::cout << "Calling Copy Constructor\n";

        m_pString = other.m_pString;

 

        //The following lines are for deep copy implementation

        //int len = strlen(other.m_pString);

        //m_pString = new char [len + 1];

        //strcpy(m_pString, other.m_pString);

    }

 

    const MyString& operator = (const MyString &other)

    {

        std::cout << "Calling assignment operator\n";

        int len = strlen(other.m_pString);

        m_pString = new char [len + 1];

        strcpy(m_pString, other.m_pString);

        return *this;

    }

    operator const char*()

    {

        return this->m_pString;

    }

};

 

int _tmain(int argc, _TCHAR* argv[])

{

    MyString str1("Welcome");

    MyString str2 = str1; // calling copy constructor using shallow copy

    //MyString str2;

    //str2 = str1; // calling assignment operator using deep copy

 

    return 0;

}

Output


Calling Parameterized Constructor

Calling Copy Constructor