Вызов конструктора в С++

По сути, у меня тот же вопрос, что и в этом сообщении, но когда я пошел тестировать лучший ответ, я не получил ожидаемых результатов.

У меня есть следующий класс:

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;
    }
};

просто для отслеживания вызываемых конструкторов. Затем у меня есть следующий код в основном:

Test t1 = Test();

Основываясь на ответе в связанном посте, я ожидаю четыре строки вывода: одну для создания временного объекта по умолчанию, одну для копирования и два вызова деструктора: одну для уничтожения временного объекта и другую для t1. Однако я получаю только две строки: «конструктор по умолчанию» и «деструктор», предположительно обе для t1 после выхода из main(). Кто-нибудь может подробно объяснить, что происходит? Может ли кто-нибудь также объяснить, почему здесь используется оператор присваивания? Разве он не должен ожидать lvalue (потому что для этого требуется ссылка lvalue), тогда как временный объект является rvalue?


person Kerry    schedule 07.04.2016    source источник
comment
en.cppreference.com/w/cpp/language/copy_elision C++ не поддерживает не нужно вызывать конструкторы, когда это на самом деле не нужно.   -  person xaxxon    schedule 07.04.2016
comment
Сотни дубликатов.   -  person Kerrek SB    schedule 07.04.2016
comment
Я думаю, что это проблема, когда компилятор использует ярлык, фактически не вызывая оператор присваивания. Попробуйте тест t1, t2; т1 = т2; (Это работает так, как ожидалось, поскольку на самом деле заставляет компилятор использовать оператор присваивания.   -  person Chris Britt    schedule 07.04.2016
comment
@ChrisBritt опускается конструктор копирования, а не назначение.   -  person Ryan Haining    schedule 07.04.2016
comment
@RyanHaining Правда, мой плохой.   -  person Chris Britt    schedule 07.04.2016


Ответы (1)


C++ не должен вызывать конструкторы, когда это на самом деле не нужно. В вашем случае он знает, что объект создается с результатами вызова справа, поэтому он пропускает промежуточные шаги.

Вы можете увидеть ожидаемые результаты, добавив флаг -fno-elide-constructors, но на практике этого никогда не следует делать.

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

посмотреть вживую: http://melpon.org/wandbox/permlink/OoxFy1dV6LB3QDbH

person xaxxon    schedule 07.04.2016