I wrote this simple code to understand the functionality of copy constructor in c++. When I initialize "obj2" with "obj1" directly it is working fine. But when I try to initialize "obj2" with the returning object from the function "func()" it is showing an error:
error: cannot bind non-const lvalue reference of type 'MyInt&' to an rvalue of type 'MyInt'
Why is this happening?
Code:
#include<bits/stdc++.h>
using namespace std;
class MyInt
{
int x;
public:
MyInt()
{
cout<< "default constructor called" << endl;
}
MyInt(int x)
{
cout<< "constructor with initializer called" << endl;
this->x = x;
}
MyInt(MyInt& obj) {
this->x = obj.x;
cout<< "copy constructor called" << endl;
}
~MyInt()
{
cout<< "destructor called" << endl;
}
};
MyInt func(MyInt obj)
{
return obj;
}
int main()
{
MyInt ob1(2);
//MyInt ob2 = ob1; //works perfectly fine: "copy constructor called"
MyInt ob2 = func(ob1); //giving error
}
You have defined this constructor:
MyInt(MyInt& obj) {
this->x = obj.x;
cout<< "copy constructor called" << endl;
}
The parameter MyInt& obj
is a reference, and it is not const
.
This indicates that you wish to be able to both read from it and write to it.
C++ will protect you from certain mistakes by not allowing a temporary (also called an "rvalue") to be passed as this parameter. Because writing to a temporary is almost certainly a mistake. Whatever you write will get lost.
Your function, however, does not write to that parameter. You can indicate that you don't intend to write to a reference by making it const
.
MyInt(const MyInt& obj) {
this->x = obj.x;
cout<< "copy constructor called" << endl;
}
This change will allow temporaries to be passed to this constructor.