top of page

Copy Constructor

A copy constructor is a special constructor which is called whenever an object is created as a copy of another.

 

A copy constructor will be  of the form

    A::A(const &A)

or

   A::A(&A)

e.g.  The line


A obj3 = obj1;


Here obj3 is should be created as a copy of obj1.  Program calls copy constructor to create obj3.

Copy ctor is also called when an object is sent as a value parameter to a function or an object is returned from a function as a value. Remember that value parameters are always copies of arguments.

 

By default, compiler provides a copy constructor to every class, which copies the objects bitwise (shallow copy) - it copies all the sub-objects without modifying the argument.

 

This ctor is sufficient in most cases unless the class uses dynamic memory.


You can write your own copy constructor as shown below.

 

Copy constructor takes one reference parameter of the same class.

The single parameter to the copy constructor should be a reference to object of the same class.

 

When is a copy constructor called?

A Copy constructor is called when

  1. An object is initialized with another object of same class.   A obj2 = obj1;

  2. An object is sent as a value parameter to a function.    void printA(A obj1);

  3. An object is returned from a function by value.       A foo(int n);

Let us look at an example of copy constructor and its usage.

In the program above, the Number class has both constructor and a copy constructor. (Note that the one parameter constructor in this case is default constructor also)

First object obj1 is created using para-ctor. obj2 is a copy of obj1. So it calls copy constructor. We also have a function printA which takes Number object as a value parameter. This function is called with obj1. This also calls the copy constructor.

Let us see what will be the output of the program.

$ ./a.out
Constructor
copy creation Copy Constructor
Fn call with value parameter Copy Constructor
Number is 10

 
Shallow copy and deep copy

 

Copy constructor provided by compiler does shallow copy; all members of new object are copied from respective members of original object bit by bit.

 

If there are pointers in the object, the constructor just copies the pointer addresses to new object, instead of allocating new memory and copying the contents to this new memory. Hence pointers of both original object and new object point to the same location.

 

If one of the objects is destroyed, then pointer of other object becomes dangling pointer and causes program to crash.

Let us look at an example.

The class A allocates dynamic memory in its constructor using new operator. And it deletes the memory in the destructor. The class does not have a copy constructor. So compiler provides a copy ctor which does a shallow copy.

 

What happens when we run the program?

 

./a.out
*** Error in `./a.out': double free or corruption (fasttop): 0x0000000001e02010 ***
Aborted

 

This program crashes because both obj1 and obj2 have same pointer ptr. When obj2 is destroyed, the pointer ptr is released. Now destructor call of obj1 tries to release this dangling pointer again and this crashes the program.

To overcome such errors, we have to write our own copy constructor which does a deep copy - by allocating memory to the new object and then copying the contents.

In the example above, the  copy constructor takes care of memory allocation and then copying the elements. 

 

Note:

  1. If a class does not have dynamic allocation, then the compiler provided copy constructor is sufficient

  2. If a class has dynamically allocated members, then it must re-define all the 4 methods provided by the compiler viz. default constructor, copy constructor, assignment operator and destructor.

bottom of page