Reputation: 23
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
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
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