Второй путь неправильный, первый правильный.
Вы вызываете оператор присваивания для экземпляра T, связанного с данными мусора.Оператор присваивания ожидает, что экземпляр был правильно инициализирован - например, он может удалить переменные-члены перед присваиванием, что приведет к всевозможным смешным сбоям.См., Например:
struct Foo {
std::string * Data;
Foo() : Data(0) {}
Foo(Foo const & R) { Data = new std::string(*R.Data); }
~Foo() { delete Data; }
Foo & operator=(Foo const & R) {
delete Data;
Data = new std::string(*R.Data);
return *this;
}
};
Первый способ обеспечит вызов Foo::Foo()
, что приведет к правильной инициализации Data
.Второй способ приведет к delete Data;
, где Data
указывает на какое-то случайное место в памяти.
РЕДАКТИРОВАТЬ:
Вы можете проверить это следующим образом:
void* mem = malloc(sizeof(Foo));
memset(mem, 0xCC, sizeof(Foo)); // malloc doesn't guarantee 0-init
Foo* obj = new(mem) Foo();
А:
Foo * obj = (Foo*)malloc(sizeof(Foo));
memset(obj, 0xCC, sizeof(Foo)); // malloc doesn't guarantee 0-init
*obj = Foo(); // Crash