Ответ 1
Инициализация - это своего рода PITA, чтобы следовать в стандарте... Тем не менее, два уже существующих ответа неверны в том, что они пропускают, и это заставляет их утверждать, что нет никакой разницы.
Существует огромная разница между вызовами new T
и new T()
в классах, где нет определяемого пользователем конструктора. В первом случае объект будет инициализирован по умолчанию, а во втором случае он будет "инициализирован значением". Если объект содержит какой-либо подобъект POD, то первый оставит подбот POD неинициализированным, а второй установит каждый подэлемент в 0.
struct test {
int x;
std::string s;
};
int main() {
std::auto_ptr<test> a( new test );
assert( a->s.empty() ); // ok, s is string, has default constructor
// default constructor sets it to empty
// assert( a->x == 0 ); // this cannot be asserted, the value of a->x is
// undefined
std::auto_ptr<test> b( new test() );
assert( b->s.empty() ); // again, the string constructor sets to empty
assert( b->x == 0 ); // this is guaranteed by *value-initialization*
}
Для длинной дороги... default-initialize для определенного пользователем класса означает вызов конструктора по умолчанию. В случае без конструктора по умолчанию, предоставленного пользователем, он будет вызывать неявно определенный конструктор по умолчанию, который эквивалентен конструктору с пустым списком инициализации и пустым телом (test::test() {}
), что, в свою очередь, приведет к инициализации по умолчанию для каждого не-POD подобъектом, и оставить все подобъекты POD неинициализированными. Поскольку std::string
имеет пользователя (по некоторому определению пользователя, который включает в себя стандартную библиотеку), предоставленный конструктор, он вызывается таким конструктором, но он не будет выполнять никакой реальной инициализации в члене x
.
То есть для класса с предоставленным пользователем конструктором по умолчанию new T
и new T()
совпадают. Для класса без такого конструктора это зависит от содержимого класса.