Инициализация - это своего рода PITA, которой нужно следовать в стандарте ... Тем не менее, два уже существующих ответа неверны в том, что они пропускают, и это заставляет их утверждать, что нет никакой разницы.
Существуетогромная разница между вызовами new T
и new T()
в классах, где нет определенного пользователем конструктора.В первом случае объект будет default-initialized , тогда как во втором случае он будет `value-initialized *.Если объект содержит какой-либо подобъект 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
имеет user (по определению пользователя, который включает в себя стандартного средства записи библиотеки), он будет вызывать такой конструктор, но он не будет выполнять никакой реальной инициализации члена x
.
То есть для класса с конструктором по умолчанию, предоставленным пользователем, new T
и new T()
одинаковы.Для класса без такого конструктора это зависит от содержимого класса.