Copy constructor in C++
I am not sure why Interviewers give so much importance to copy constructor. Anyway, copy constructor is a constructor which copies one object to another.
A obj1;
A obj2 = obj1;
Now obj2 is constructed using copy constructor. Always. You might have earlier created some classes without any constructors but used assignments similar to the ones above. What happened then? Even then, copy constructor was used for copying but this copy constructor was provided by compiler which copied each member of obj2 to corresponding member of obj1.
A obj1(10);//obj1 will have n as 10 and anotherNum as 100
A obj2=obj1;
Now obj1.n is copied to obj2.n and obj1.anotherNum is copied to obj2.anotherNum.
But this copy is called shallow copy and causes a problem if the members are pointers. In such a case two objects will have pointers pointing to same location. If one of them is destructed, the other object will cause memory error. To avoid such problems, we should do deep copy and we should write our own copy constructor.
One point to remember is copy constructor needs the parameter to be of the reference type. If not, the compiler gives an error.
Now let us consider another example of copy constructor which needs deep copy.
We saw one example of copy constructor. Where else will this be called? A copy constructor is also called when an object is passed as a value parameter to a function and when an object is returned by value from a function.
void my_function(A par1,int n);//calls copy constructor for par1
A my_second_function(int m);//returns A object . Calls copy constructor for return value
The best way to visualize all this is, write a copy constructor for your class with a cout statement in it. And observe when it will be called.
But if the parameter to the function or the return value is of type reference to an object, then the copy constructor will not be called.
A obj1;
A obj2 = obj1;
Now obj2 is constructed using copy constructor. Always. You might have earlier created some classes without any constructors but used assignments similar to the ones above. What happened then? Even then, copy constructor was used for copying but this copy constructor was provided by compiler which copied each member of obj2 to corresponding member of obj1.
class A { private: int n; int anotherNum ; public: A(int num) { n = num; anotherNum=n*n; } };Now if you use statements like
A obj1(10);//obj1 will have n as 10 and anotherNum as 100
A obj2=obj1;
Now obj1.n is copied to obj2.n and obj1.anotherNum is copied to obj2.anotherNum.
But this copy is called shallow copy and causes a problem if the members are pointers. In such a case two objects will have pointers pointing to same location. If one of them is destructed, the other object will cause memory error. To avoid such problems, we should do deep copy and we should write our own copy constructor.
class A { private: int n; int anotherNum ; public: A(int num) { n = num; anotherNum=n*n; } A(A&other) { n = other.n; anotherNum=other.anotherNum; } };Second constructor we see is the copy constructor. We are copying each member of parameter to corresponding member of our object.
One point to remember is copy constructor needs the parameter to be of the reference type. If not, the compiler gives an error.
Now let us consider another example of copy constructor which needs deep copy.
class B { int *a; int sz; public: B(int sz)//constructor { this->sz = sz; a = new int[sz]; for(int i=0;i<sz;i++) a[i]=0; } ~B() { delete[]a; } B(const B&b1)//copy constructor { this->sz = b1.sz; a = new int[sz]; for(int i=0;i<sz;i++) a[i] = b1.a[i]; } };Observe the new operator used to allocate memory in copy constructor. We are allocating memory and the pointer points to this new location. Then the elements are copied to this new location. In this example a compiler provided copy constructor would have caused the program to crash because of memory error - infamous segmentation fault in Linux systems.
We saw one example of copy constructor. Where else will this be called? A copy constructor is also called when an object is passed as a value parameter to a function and when an object is returned by value from a function.
void my_function(A par1,int n);//calls copy constructor for par1
A my_second_function(int m);//returns A object . Calls copy constructor for return value
The best way to visualize all this is, write a copy constructor for your class with a cout statement in it. And observe when it will be called.
But if the parameter to the function or the return value is of type reference to an object, then the copy constructor will not be called.
#include<iostream> using std::cout; class Circle { int radius; int centerx,centery; public: Circle(int r=0) { radius=r; centerx=centery=0; cout<<"parameterized constructor is called\n"; } Circle(const Circle &c) { radius=c.radius; centerx=c.centerx; centery=c.centery; cout<<"copy constructor is called\n"; } void print() { cout<<"Center is "<<centerx<<" , "<<centery<<"\n"; cout<<"Radius is "<<radius<<"\n"; } friend float findArea(Circle c ); }; float findArea(Circle c) { float area = 22/7.0 * c.radius * c.radius; } int main() { Circle c1; cout<<"after c1 declaration\n"; Circle c2(3); cout<<"after c2 declaration\n"; Circle c3=c2; cout<<"after c3 declaration\n"; float area = findArea(c1); cout<<"After calling find area function\n"; }
A last thing to remember is copy constructor is different from assignment operator. An assignment operator is used when the object is already present and we are assigning new value to it unlike copy constructor.
A obj1; A obj2; obj2 =obj1 ;//calls assignment operator A obj3=obj1;//calls copy constructor
nice... explanation...
ReplyDelete