2

I'm trying to understand the behaviour of copy constructors and how memory and temporary objects are created and copied. I have disabled copy elision in g++ to get a better idea of what is happening. Here is my code:

//====================
#include <iostream>
using namespace std;

class Human
{
public:
    Human()
    {
        cout << "Human constructed: " << this << endl;
    }

    Human(const Human &)
    {
        cout << "Human copied:      " << this << endl;
    }

    ~Human()
    {
        cout << "Human destroyed:   " << this <<  endl;
    }
};

class Creature
{
public:
    Creature()
    {
        cout << "Creature constructed: " << this <<  endl;
    }

    ~Creature()
    {
        cout << "Creature destroyed:   " << this <<  endl;
    }

    Human create_human()
    {
        Human mySecondHumanObject;
        return mySecondHumanObject;
    }
};


int main()
{
    Creature myCreatureObject;
    Human myFirstHumanObject = myCreatureObject.create_human();
    cout << "myFirstHumanObject :" << &myFirstHumanObject << endl;
    return 0;
}

Output:

Creature constructed: 0x7fff5b8d9d95
Human constructed: 0x7fff5b8d9d67    // mySecondHumanObject constructed
Human copied:      0x7fff5b8d9d97    // copied to where???
Human destroyed:   0x7fff5b8d9d67    // mySecondHumanObject destroyed at return
Human copied:      0x7fff5b8d9d96    // copied to myFirstHumanObject
Human destroyed:   0x7fff5b8d9d97    // object copied at return now destroyed
myFirstHumanObject :0x7fff5b8d9d96
Human destroyed:   0x7fff5b8d9d96
Creature destroyed:   0x7fff5b8d9d95

Could someone shed a bit of light on the mechanism as to how this works? I am slightly confused as to why the first invocation of the copy constructor occurs (copied into mem Address: 0x7fff5b8d9d97). Why is not just copied directly into the myFirstHumanObject at mem address: 0x7fff5b8d9d96)?

kahamster
  • 51
  • 5
  • 1
    *Why is not just copied directly into...* -- But you stated that you turned off copy elision. Why the surprise? – PaulMcKenzie Nov 01 '18 at 11:07
  • yes, I'm wondering why exactly it is necessary for the compiler to make all these copies in the first place? I guess my question is more interested in what is happening in the memory. Why is it not possible to just just copy from 0x7fff5b8d9d67 to 0x7fff5b8d9d96 ? – kahamster Nov 01 '18 at 11:24

1 Answers1

2

If you were to write simple myCreatureObject.create_human(); without assigning the result anywhere, would that Human not be created and destoryed? Of course it would exist, and you'd see the output. The function returns a value, so a temporary object must be created with that value.

Since you turned off copy elision, that temporary is going to need to be created, even when using it to initialize another object. Copy elision often eliminates far more than just one copy. It can eliminate entire chains. And when it's turned off, those chains reappear, like you see.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458