Abdellah
Abdellah

Reputation: 23

create a deep copy by using copy constructor in c++

I'm beginner in C++ and I have a problem with my copy constructor: I need to do a deep copy, because my class has a pointers. I already defined a copy constructor and also I create an object N1(2,3) from my class Number. A second object N2 is intialized by using copy constructor.

But the copy constructor doesn't do a deep copy because, when I change the value of object N1, object N2 also has its values changed. I want to have two separate objects by using copy constructor.

My class Number:

   class Number
   {
   private:
    int* a;
    int* b;

    public:
    //default constructor:
    Number() {
        a = new int;
        b = new int;
        *a = 0;
        *b = 0;
    }
    
    //constructor with arguments:
    Number(int val1, int val2) {
        a = new int;
        b = new int;
        *a = val1; 
        *b = val2;
    }
    //copy constructor:
    Number(const Number& other) {
        a = new int;
        b = new int;
       *a = *(other.a)
       *b = *(other.b);
    }

    //getters and setters:
    int getA() {
        return *a;
    }
    int getB() {
        return *b;
    }
    void setA(int val) {
        *a = val;
    }
    void setB(int val) {
        *b = val;
    }

    //method print:
    void print() {
        cout << "value of a: " << *a << " value of b: " << *b << endl;
    }
};

My main:

int main()
{
    Number N1(2,3), N2;

    N1.print(); //2-3
    N2.print(); //0-0

    N2 = N1;
    
    N1.print(); //2-3
    N2.print(); //2-3

    N1.setA(12);

    N1.print(); //12-3
    N2.print(); //12-3 i want object N2 have 2-3 values not 12-3 like N1
                           //i want to separate N1 from N2 by using copy constructor 
}

I'm trying to define this copy constructor but it's not working:

       //copy constructor:
    Number(const Number& other) {
        a = new int;
        b = new int;
       *a = *(other.a)
       *b = *(other.b);
    }

Upvotes: 1

Views: 377

Answers (2)

sweenish
sweenish

Reputation: 5202

The issue you're seeing is lack of Complete Rule of 0/3/5.

And the fact that you are not invoking your copy constructor. You are invoking the assignment operator, which has been provided for you, and is shallow.

The line Number N1(2,3), N2; has declared N2 using the default constructor.

The line N2 = N1; then shallow assignsN1 because you didn't provide operator=().

If you wanted to invoke the copy constructor, you have to do so at the time of declaration. It is a constructor, after all.

Something like Number N2(N1);.

In order to complete your code, you still need to write a destructor as well as assignment operator. Then it's time to learn about move semantics.

Upvotes: 2

Adrian Mole
Adrian Mole

Reputation: 51825

The code, N2 = N1;, does not invoke the copy constructor because N2 has already been constructed. Rather, it calls the assignment operator. As you have not provided a definition for that, the default is to make a shallow copy (i.e. just copy/overwrite the actual pointers, as you observe).

You need to define a deep-copying assignment operator; something like this:

    // assignment operator:
    Number& operator=(const Number& other) {
        *a = *(other.a);
        *b = *(other.b);
        return *this;
    }

Note, however, that were you to use the = N1 syntax in your declaration of N2 (as below), then that would call the copy constructor:

    Number N2 = N1; // This calls the copy constructor

Upvotes: 2

Related Questions