jeudi 2 juin 2016

Move Constructor is called twice in C++?

Look at this code:

class Foo
{
public:

    string name;

    Foo(string n) : name{n}
    {
        cout << "CTOR (" << name << ")" << endl;
    }

    Foo(Foo&& moved)
    {
        cout << "MOVE CTOR (moving " << moved.name << " into -> " << name << ")" << endl;

        name = moved.name + " ###";
    }

    ~Foo()
    {
        cout << "DTOR of " << name << endl;
    }
};

Foo f()
{
    return Foo("Hello");
}

int main()
{        
    Foo myObject = f();

    cout << endl << endl;
    cout << "NOW myObject IS EQUAL TO: " << myObject.name;
    cout << endl << endl;        

    return 0;
}

The output is:

[1] CTOR (Hello)

[2] MOVE CTOR (moving Hello into -> )

[3] DTOR of Hello

[4] MOVE CTOR (moving Hello ### into -> )

[5] DTOR of Hello ###

[6] NOW two IS EQUAL TO: Hello ### ###

[7] DTOR of Hello ### ###

Important note: I have disabled the Copy Elision optimization using -fno-elide-constructors for testing purposes.

The function f() constructs a temporary [1] and returns it calling the Move Constructor to "move" the resources from that temporary to myObject [2] (additionally, it adds 3 # symbols).

Eventually, the temporary is destructed [3]


I now expect myObject to be fully constructed and its name attribute to be Hello ###

Instead, the Move Constructor gets called AGAIN, so I'm left with Hello ### ###

Aucun commentaire:

Enregistrer un commentaire