Please login

Prime

Prepinsta Prime

Video courses for company/skill based Preparation

(Check all courses)
Get Prime Video
Prime

Prepinsta Prime

Purchase mock tests for company/skill building

(Check all mocks)
Get Prime mock

Copy Constructor in C++

C++ Copy Constructor

Copy Constructor is a type where in we use an existing object to create multiples construction initialisations for newer objects that will be created. It is a special member function of the class.

Copy Constructor in C++

Copy Constructor

These are the special type of Constructors which takes an object as an argument, and is used to copy values of data members of one object into another object.

Syntax –

class_name (class-name &){
....
}
  • Copy Constructor is a type of constructor which is used to create a copy of an already existing object of a class type.
  • It is usually of the form X (X&), where X is the class name.
  • The compiler provides a default Copy Constructor to all the classes.
#include <iostream>
using namespace std;

class PrepInsta
{
private:
int x, y;
public:
PrepInsta()
{

}
PrepInsta(int x1, int y1)
{
x = x1;
y = y1;

cout << "Parameterized constructor called here" << endl;

}

// User defined Copy constructor
PrepInsta(const PrepInsta &p2)
{
x = p2.x;
y = p2.y;

cout << "Copy constructor called here" << endl;

}

int getX()
{
return x;

}
int getY()
{
return y;

}
};

int main()
{
// Trying to call parameterized constructor here
PrepInsta p1(10, 15);
// Trying to call copy constructor here
PrepInsta p2 = p1;
// Trying to call Copy constructor here
PrepInsta p3(p1);
PrepInsta p4;
// Here there is no copy constructor called only assignment operator happens
p4 = p1;
cout << "For p4 & p3 no copy constructor called only assignment operation happens" << endl;

// displaying values for both constructors
cout << "p1.x = " << p1.getX() << ", p1.y = " << p1.getY();
cout << "\np2.x = " << p2.getX() << ", p2.y = " << p2.getY();

cout << "\np3.x = " << p3.getX() << ", p3.y = " << p3.getY();
cout << "\np4.x = " << p4.getX() << ", p4.y = " << p4.getY();
return 0;
}

In the above example there are two ways to call copy constructor –

  • PrepInsta p2 = p1;
  • PrepInsta p3(p1);

However, PrepInsta p4; followed by p4 = p1; doesn’t call copy constructor, its just simply and assignment operator

Output

Parameterized constructor called here 
Copy constructor called here
Copy constructor called here
For p4 & p3 no copy constructor called only assignment operation happens

p1.x = 10, p1.y = 15
p2.x = 10, p2.y = 15
p3.x = 10, p3.y = 15
p4.x = 10, p4.y = 15

Reference

Types of Copy Constructors

It is really great way of creating new object initialisations and is still widely used by programmers.

There are two types of copy constructors which are –

  • Default Copy Constructors (Does Shallow Copying)
  • User Defined Copy Constructors (Does Deep Copying)

We will learn more about these two in detail below –

Types of Copy Constructors

  • Default Copy Constructors – When we don’t define our own version of constructor in that case the compiler creates its own version of copy constructor. The type of copies that are made by default are called shallow copies and thus Default constructor does shallow copying. We will learn more about in detail below
  • User defined copy constructor – These type of constructors are user enforced and manually created constructors, these do deep construction, we will learn more about the same in detail below. Also in above example we did deep copy.

Mostly these deal with pointers and dynamically allocated resources.

Copy Constructor in C++ Detailed

Shallow and Deep copy

Shallow Copy Constructor in C++

Shallow Copy Constructor

These are in cases when a default copy constructor is created by the compiler itself. In such cases, as explained in the image, there maybe two different objects, once of which is created via default constructor called by compiler.

The objects do not have their individual storage locations, however, are referring to common storage location.

Let us see and example to see how this works –

#include<iostream>
#include<string.h>

using namespace std;
class PrepInsta
{
char *prepString;
public:
PrepInsta(const char *prepString1)
{
//We are invoiking Dynamic memory allocation here
prepString = new char[16];
strcpy(prepString, prepString1);
}
/* concatenate method */
void concatenate(const char *prepString1)
{
// using function to Concatenating two strings
strcat(prepString, prepString1);
}

~PrepInsta ()
{
delete [] prepString;
}
void print()
{
cout<<prepString<<endl;
}
};
/* main function */
int main()
{
PrepInsta obj1("Prep");
PrepInsta obj2 = obj1;
//Copy constructor

cout<<"Before concatenation - "<<endl;

obj1.print();
obj2.print();
obj1.concatenate("Insta");

//obj1 is invoking concatenate()

cout<<"After concatenation - "<<endl;

obj1.print();
obj2.print();

//here values for both of the objects have changed together
//because they had shared memory in this case
return 0;
}

Output

Before concatenation - 
Prep
Prep
After concatenation -
PrepInsta
PrepInsta

Here , we only used concatenate function with object 1 but we notice in the output that the value of object 2 has also changed this, is the problem with shallow copy constructor.

Deep Copy Constructor in C++

Deep Copy Constructor

At times when there is involvement of pointers and in some cases run time allocation of resources,  like file handle, a network connection and others. We may encounter problem with direct assignment operator.

Let us see what happens when we have a forced user defined constructor which as explained from the image, will do deep constructing, i.e. each object will have their memory location individually –

#include <iostream>
#include <string.h>
using namespace std;

class PrepInsta
{
char *prepString;
public:
PrepInsta (const char *str)
{
//We are invoking Dynamic memory allocation here

prepString = new char[16];
strcpy(prepString, str);
}

// here we are doing the change of adding additional code
// for copy constructor
PrepInsta (const PrepInsta &x2)
{
//We are invoking Dynamic memory allocation here

prepString = new char[16];
strcpy(prepString, x2.prepString);
}

void concatenate(const char *prepString1)
{
// using function to Concatenating two strings
strcat(prepString, prepString1);
}

~PrepInsta()
{
delete [] prepString;
}

void print()
{
cout<<prepString<<endl;
}
};

/* main function */
int main()
{
PrepInsta p1("Prep");
PrepInsta p2 = p1; //copy constructor

cout<<"Before concatenation - "<<endl;
p1.print();
p2.print();
p1.concatenate("Insta");
cout<<"After concatenation - "<<endl;
p1.print();
p2.print();

return 0;
}

In this case the output would be –

Output –

Before concatenation - 
Prep
Prep
After concatenation -
PrepInsta
Prep

Here we have solved the problem as