Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expected object construction is missing [duplicate]

Tags:

c++

c++11

class A
{
public:

    A ()
    {
        wcout << L"Empty constructed." << endl;
    }

    A (LPCWSTR Name)
        : m_Name(Name)
    {
        wcout << L"Constructed." << endl;
    }

    friend void swap (A& Lhs, A& Rhs)
    {
        using std::swap;

        swap(Lhs.m_Name, Rhs.m_Name);
    }

    A (A&& Other)
    {
        wcout << L"Move constructed." << endl;

        swap(*this, Other);
    }

    A (const A& Other)
        : m_Name(Other.m_Name)
    {
        wcout << L"Copy constructed." << endl;
    }

    A& operator= (A Other)
    {
        wcout << L"Assignment." << endl;

        swap(*this, Other);

        return *this;
    }

    ~A ()
    {
        wcout << L"Destroyed: " << m_Name.GetString() << endl;
    }

private:

    CString m_Name;
};


int
wmain ()
{
    A a;

    a = A(L"Name"); // Where is the construction of this temp object?

    return 0;
}

This is the output I get for the above code:

Empty constructed.
Constructed.
Assignment.
Destroyed:
Destroyed: Name

See the line with the comment. What I expected is for a temp object to get constructed there, and the argument Other in the operator= would get move-constructed from that temp-object. What's happening here?

like image 502
TripShock Avatar asked Sep 26 '26 08:09

TripShock


2 Answers

The output that says "Constructed" is actually the feedback from the construction of that temporary object.

If you are looking for an additional copy-construction (or move-construction) of Other parameter of copy-assignment operator, it was probably eliminated by copy elision. Your A(L"Name") is immediately constructed and used as that Other parameter. No extra copying (or moving) is performed.

like image 179
AnT Avatar answered Sep 28 '26 20:09

AnT


You can use an interactive debugger to see for yourself. However, your answer to where "Name" got constructed is this:

A (LPCWSTR Name) 
    : m_Name(Name) 
{ 
    wcout << L"Constructed." << endl; 
} 

and

 a = A(L"Name");

Your code constructed an empty object at the code line A a;.

It then constructed "Name".

Then it swapped the two's CString m_Name; (shown by the output Assignment).

Then it destructed the original object holding "Name" (A(L"Name")).

Then it destructed the original empty object that is now holding "Name" in its m_Name.

like image 34
StarPilot Avatar answered Sep 28 '26 22:09

StarPilot



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!