Search code examples
c++initializationcopy-constructor

Cannot initialize object with returning value of a function.. Why?


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
}

Solution

  • 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.