Open In App

Why copy constructor argument should be const in C++?

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

When we create our own copy constructor, we pass an object by reference and we generally pass it as a const reference. 
One reason for passing const reference is, we should use const in C++ wherever possible so that objects are not accidentally modified. This is one good reason for passing reference as const, but there is more to it. For example, predict the output of following C++ program. Assume that copy elision is not done by compiler.

C




#include<iostream>
using namespace std;
 
class Test
{
/* Class data members */
public:
Test(Test &t) { /* Copy data members from t*/}
Test()     { /* Initialize data members */ }
};
 
Test fun()
{
    cout << "fun() Called\n";
    Test t;
    return t;
}
 
int main()
{
    Test t1;
    Test t2 = fun();
    return 0;
}


Output: 

 Compiler Error in line "Test t2 = fun();" 

The program looks fine at first look, but it has compiler error. If we add const in copy constructor, the program works fine, i.e., we change copy constructor to following. 
 

C




Test(const Test &t) { cout << "Copy Constructor Called\n"; }


Or if we change the line “Test t2 = fun();” to following two lines, then also the program works fine.
 

C




Test t2;
t2 = fun();


In the above codes, what’s actually happening?

It gets executed but the copy constructor is not called, instead, it calls the default constructor where the assignment operator is overloaded. Even if we have an explicitly overloaded assignment operator, it is not going to call it. 

The function fun() returns by value. So the compiler creates a temporary object which is copied to t2 using the copy constructor in the original program (The temporary object is passed as an argument to the copy constructor). The reason for compiler error is that compiler-created temporary objects cannot be bound to non-const references and the original program tries to do that. It doesn’t make sense to modify compiler-created temporary objects as they can die at any moment. (generally at the end of the full expression where it is created)

In simpler terms,

In C++, temporary objects are objects that are created during the evaluation of an expression, typically for immediate use and  to be copied to any named variable.

The error “compiler created temporary objects cannot be bound to non-const references” is related to binding temporary objects to non-const references. This means that a temporary object cannot be directly assigned to a non-const reference variable.
To resolve this, you have two options:

1. Use a const reference in the function parameter to increase the lifetime of the temporary object.
2. Use a named variable to store the value and then pass it to the function.

Using a const reference allows you to read the value but not modify it within the function, which is a common approach when working with temporary objects. Alternatively, using a named variable ensures that the object’s lifetime extends to the function call and beyond, avoiding the issue with temporaries.

This article is compiled by Abhay Rathi.
 



Last Updated : 21 Sep, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads