Tutorial Study Image

C++ Copy Constructors


January 19, 2023, Learn eTutorial
588

The copy constructors will be explained with examples in this tutorial, along with their uses and how to make a copy of an object in C++.

An Introduction to the C++ Copy Constructor

A copy constructor is a particular type of constructor that can be used mainly to create a copy of an existing object of a class. To be specific, it copies the values of the member variables from the existing object into the member variables of the new object. 

Basics of the copy constructor

  • In C++, the copy constructor is a parametrized constructor which is used to initialize copies of objects.
  • It uses values from the old object in order to initialize the new object.
  • Copy initialization is the process of initializing members of an object mainly using a copy constructor.
  • The copy constructor initializes one object with an existing object, both of which are members of the same class, mainly on a member-by-member copy basis, that is why it is also known as member-wise initialization.
  • The copy constructor can be explicitly defined mostly by the programmer. The compiler defines the copy constructor if the programmer doesn't.

The general function prototype of a copy constructor is as follows:

ClassName (const ClassName &old;_obj);

The following are the syntaxes for defining and calling the copy constructors:


//Definition
ClassName objectName (ClassName &existingObject;)
{
     Var1 = existingObject.Var1;
     Var2 = existingObject.Va2;
}

//Calling
ClassName ob1;
ClassName ob2(&ob1;);

 

Let us understand the syntax using an example


#include <iostream>
using namespace std;

class Transport  
{  
   public:  
    int wheels;  
    string name;
    string type;
    string color;
    
    Transport(int n)                
    {  
      wheels=n;  
    }  
     Transport(Transport &ob;)           // a copy constructor is Defined
     {
         wheels=ob.wheels;
     }
     
};  

int main()  
{  
  Transport bike1(2);                  //  1st constructor  is Called
  Transport bike2(bike1);              //Method1 is calling a copy constructor
  Transport bike3=bike2;               //Method2 is calling a copy constructor
  cout<<"bike2 has "<<bike2.wheels<<" wheels \n";
  cout<<"bike3 has "<<bike3.wheels<<" wheels";

Output:


bike2 has 2 wheels
bike3 has 2 wheels

At what point the copy constructor is called?

A copy constructor may be called in C++ in the following circumstances:

  • when an object belonging to the class is returned by a value.
  • when a class object is passed as an argument to a function by value.
  • when an object is formed based on another object belonging to the same class.
  • when a temporary object is created by the compiler.

However, there is no guarantee that a copy constructor will be called in each of these circumstances because the C++ Standard permits the compiler to remove the copy in some circumstances, such as the return value optimization (it is referred to as RVO).

Return value optimization (RVO): it is a kind of compiler optimization that is used in the C++ programming language that gets rid of the temporary object used to store a function's return value. RVO is permitted by the C++ standard to alter the observable behavior of the resulting program.

Is it possible to make the copy constructors private?

It is possible to make copy constructors private. Whenever we make a copy constructor in a class private, all objects in that class become uncopyable. When our class contains pointers or resources that are dynamically allocated, this is quite helpful.

What do you mean by Copy Elision?

Copy elision is a compiler optimization technique used in C++ computer programming that will prevent unused object copying.

In copy elision, the compiler stops the creation of unnecessary or extra copies, which saves space as well as it will be improving the program complexity (both in terms of time as well as space). As a result, the code seems to be more efficient.

In general, the C++ language standard permits implementations to use any optimization as long as the resulting program's observable behavior is the same as if, i.e. pretending, the program was executed exactly as required by the standard. Other than that, the standard also outlines a few circumstances in which copying can be avoided even though doing so might change the way the program behaves. Return value optimization is the most typical example of this.

For example, let us write a C++ program in order to understand the working of copy elision in C++?


#include <iostream>
using namespace std;

class LeT {
public:
 void print() { cout << " Hai and hello friends!"; }
};

int main()
{
 LeT L;
 for (int i = 0; i <= 2; i++) {
  L.print();
 }
 return 0;
}

 

Output:


 Hai and hello friends!
 Hai and hello friends!
 Hai and hello friends!

The compiler must now select what to print; it may choose to print the result shown above or one of the two cases shown below. This is known as return value optimization. In simple terms, Return Value Optimization (RVO) is a method that provides the compiler more control over terminating the temporary object that was generated, affecting the final program's observable behavior and attributes in the process.

Case 1
Hai and hello friends!
Hai and hello friends!
Case 2 
Hai and hello friends!

When is it necessary to utilize a user-defined copy constructor?

For each class, the C++ compiler provides a default copy constructor that performs a member-wise copy between objects if we don't define our own copy constructor. The copy constructor produced by the compiler often performs well. If an object has pointers or any other runtime resource allocations, such as a file handle, a network connection, etc., then we just need to define our own copy constructors.

Only shallow copy is performed by the default constructor.

C++ Copy Constructors

Only a user-defined copy constructor allows for a deep copy. We ensure that pointers (or references) of copied objects point to new memory locations in a user-defined copy constructor.

C++ Copy Constructors

Advantages of copy constructors in C++?

  • Using copy constructors makes object duplication simple. 
  • Copy constructors, which combine construction and replication, can be more effective than copyfrom () methods.

Disadvantages of copy constructors in C++?

  • In C + +, one of the sources of error and performance issues is an implicit copy of an object. Additionally, it makes it more difficult to follow delivery and changes to the object subroutine and makes the code harder to understand.
  • Only a small number of classes must be copied. Most classes don't need to assign operator functions or copy constructors. The majority of the time, employing pointers or references can achieve the same goal with superior efficiency. For instance, rather than passing arguments by value to a function, you can pass them by reference or pointer.
  • If your class has to be duplicated, you can offer replication methods like CopyFrom () or clone () rather than utilizing the copy constructor because the compiler cannot use this method implicitly.
  • Constructors and assignment operator functions must be explicitly disabled if your class doesn't need to duplicate them. You can achieve this by adding a null declaration of the copy constructor as well as the assignment operator function to the class's private section without including any associated definitions. Any effort to use them will therefore produce link errors.