kvway
kvway

Reputation: 494

Copy constructor confusion

Could anyone explain me the reason why is in this code defined MyClass ( const MyClass & src ) { m_X = src . m_X; } ? Without this line of code it works fine as well and gives the same output which is 32 in this case. What's the difference between having it in and not? I read that copy constructor is made automatically but when you have defined pointer in the class you should define it but i don't get why in this case.

Code below:

#include <iostream>
using namespace std;

class MyClass
{
public:
    MyClass ( int x ) : m_X ( new int ( x ) ) {}
    MyClass ( const MyClass &src ) 
    {
        m_X = src.m_X; 
    }

    void  print ( void ) const 
    { 
        cout << *m_X; 
    }

private:
    int * m_X;
};


int main ( void )
{
    MyClass a ( 32 ), c = a;
    c.print ();

    return 0;
}

Upvotes: 0

Views: 73

Answers (3)

NathanOliver
NathanOliver

Reputation: 181068

The reason you get the same output is you are doing a shallow copy just like the compiler would do. It is not enough just to copy a pointer. You need to create a new pointer and then set its value to be a copy of what you are copying from. A proper constructor would look like

MyClass ( const MyClass & src ) : m_X(new int(*src.m_X) {}

Now the copy has its own independent pointer that has the same value.

Also note that you need a destructor to delete the memory and a proper copy assignment operator as the default copy assignment operator will do the same thing as the default copy constructor.

Upvotes: 1

pm100
pm100

Reputation: 50220

The problem with the compiler generted one (and yours) is that it copies the pointer. You now have two pointers c.m_x and a.m_x both pointing at the same heap allocated object. Who owns it? What happens if you delete a, it should delete the memory it allocated (you incorrectly dont do this) , but c is still poining at it.

For this reason there is std::shared_ptr. It is designed for this case, it does the Right Thing By Magic

Replace int * m_X by std::shared_ptr<int> m_X

Upvotes: 2

Carlos
Carlos

Reputation: 356

The default copy constructor as well as your copy constructor does a member wise copy (or shallow copy). In this case you have a pointer which value is the address of where the data is located. This address what is copied.

As noted in other posts you will need to manage pointers a little better.

Upvotes: 2

Related Questions