Search code examples
c++c++11referenceauto

Does returning a reference from a function, result in creation of a new temporary object when 'auto' is used?


I wrote the following code in which a function returns a reference to a member. The return value is stored in 2 ways during 2 different calls to the function:

  1. An auto reference is used to to store the return value. As I rightly assumed, the addresses of the object to which reference is returned and the address of the auto reference that stores the return value are same, as evident from the output.
  2. 'auto' is used to store the return value. I assumed, the auto variable should result in a new object created on stack that contains copy of values of object to which reference was returned by the function. I could see that the addresses of the auto and the actual object are indeed different. However, I didn't see constructor getting called for the object created using auto. Is an object indeed created in this case ?

//Code

    #include <iostream>
    using namespace std;

    class c1 {
    private:
        int i;

    public:
        c1() {
            cout << "c1()" << endl;
            i = 10;
        }

    };

    class c2 {
    private:
        c1 mc1;

    public:
        c2() {
            cout << "c2()" << endl;
        }

        c1& getmc1() {
            cout << "address of mc1 : " << &mc1 << endl;
            return mc1;
        }
    };

    int main() {
        c2 c;
        auto& c1_1 = c.getmc1();
        cout << "address of c1_1 : " << &c1_1 << endl;

        c2 c_2;
        auto c1_2 = c_2.getmc1();
        cout << "address of c1_1 : " << &c1_1 << endl;

        return 0;
    }


//Output
c1()
c2()
address of mc1 : 00AFF82C   --> Same as below address, expected
address of c1_1 : 00AFF82C
c1()
c2()
address of mc1 : 00AFF814  --> Different from below address, expected
address of c1_1 : 00AFF82C --> why c1() constructor is not invoked ?

Edit

@NathanOliver, @Tali,

Thanks for pointing out about the copy constrcutor. I added one, and I could see the right output. I'm a beginner to C++. I missed the point that compiler generates an implicit copy constructor.

Below is the updated program.

#include <iostream>
using namespace std;

class c1 {
private:
    int i;

public:
    c1() {
        cout << "c1()" << endl;
        i = 10;
    }

    c1(c1 &c) {
        cout << "c1(c1 &c)" << endl;
        i = c.i;
    }

};

class c2 {
private:
    c1 mc1;

public:
    c2() {
        cout << "c2()" << endl;
    }

    c1& getmc1() {
        cout << "address of mc1 : " << &mc1 << endl;
        return mc1;
    }
};

int main() {
    // your code goes here
    c2 c;
    auto& c1_1 = c.getmc1();
    cout << "address of c1_1 : " << &c1_1 << endl;

    c2 c_2;
    auto c1_2 = c_2.getmc1();
    cout << "address of c1_1 : " << &c1_2 << endl;

    return 0;
}

Output:

c1()
c2()
address of mc1 : 010FFE18
address of c1_1 : 010FFE18
c1()
c2()
address of mc1 : 010FFE00
c1(c1 &c)
address of c1_1 : 010FFDF4

Solution

  • Yes the new object is constructed, but not using your c1::c1(). Such copies of objects are done using the copy constructor c1::c1(const c1 &).

    In your example, you do not provide a copy constructor so the compiler will implicitly generate one.