С++ Object Instantiation vs Assignment

В чем разница между этим:

TestClass t;

И это:

TestClass t = TestClass();

Я ожидал, что второй может вызвать конструктор дважды, а затем оператор =, но вместо этого он вызывает конструктор ровно один раз, как и первый.

Ответ 1

TestClass t;

вызывает конструктор по умолчанию.

TestClass t = TestClass();

является инициализацией копии. Он будет вызывать конструктор по умолчанию для TestClass(), а затем конструктор копирования (теоретически копирование подлежит копированию). Здесь нет назначения.

Также существует понятие прямой инициализации:

TestClass t(TestClass());

Если вы хотите использовать оператор присваивания:

TestClass t;
TestClass s;
t = s;

Ответ 2

Первый случай довольно прост - создает экземпляр с использованием конструктора по умолчанию.

Второй класс - это создание анонимного объекта, а затем вызов конструктора копирования. Обратите внимание, что здесь = не присваивается, он похож на (но не идентичный):

TestClass t(TestClass());

Мы можем убедиться, что для этого необходим конструктор копирования, если он недоступен, например:

#include <iostream>

struct TestClass {
  TestClass() { std::cout << "Ctor" << std::endl; }
  TestClass(const TestClass&)  = delete;
};

int main() {
  TestClass t = TestClass();
}

Что не удается скомпилировать из-за конструктора удаленной копии. (В С++ 03 вы можете использовать private:).

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

Ответ 3

В первом вы вызываете конструктор по умолчанию неявно. А во втором вы вызываете его явно.

Ответ 4

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

Изменить: Я, конечно, сделал слишком большие выводы из имени типа, которое вы использовали. Вышеприведенное предложение применяется только для типов классов (т.е. Не POD). Для типов POD первая оставляет переменную неинициализированной, а последняя инициализирует ее так называемым значением по умолчанию.