1

I have essentially the same question as this post, but when I went to test the top answer, I did not get the expected results.

I have the following class:

class Test
{
public:
    Test()
    {
        std::cout << "default constructor" << std::endl;
    }

    Test(const Test &other)
    {
        std::cout << "copy constructor" << std::endl;
    }

    Test& operator=(const Test &other)
    {
        std::cout << "assignment operator" << std::endl;
        return *this;
    }

    ~Test()
    {
        std::cout << "destructor" << std::endl;
    }
};

just to track which constructors are called. I then have the following code in the main:

Test t1 = Test();

Based on the answer in the linked post, I would expect four lines of output: one for default constructing the temporary object, one for copying, and two destructor calls: one for the destruction of the temporary and the other for t1. However, I only get two lines: "default constructor" and "destructor", presumably both for t1 after exiting main(). Could someone explain in detail what is happening? Could someone also explain why the assignment operator is used here? Shouldn't it be expecting an lvalue (because it require an lvalue ref) whereas the temporary object is an rvalue?

Community
  • 1
  • 1
Kerry
  • 115
  • 1
  • 7

1 Answers1

3

C++ doesn't have to call constructors when it's not actually necessary. In your case, it knows the object is being created with the results of the call on the right, so it skips the intermediary steps.

You can see the results you expect by adding the -fno-elide-constructors flag, but you should never do this in practice.

http://en.cppreference.com/w/cpp/language/copy_elision

see it live: http://melpon.org/wandbox/permlink/OoxFy1dV6LB3QDbH

xaxxon
  • 19,189
  • 5
  • 50
  • 80