Возможно, для вас будет новостью, что в C++ можно писать как «new T()», так и «new T».
Можно сперва подумать, что это какой-то синтаксический сахар, и эти конструкции полностью идентичны. Это не так. Конечно, если явно определен конструктор T::T(), то, non c’è problema, вызовется именно он и разницы не будет никакой.
Если же явного конструктора по умолчанию не определено, то «new T()», в отличие от «new T», заполнит все поля объекта нулями. Если быть совсем точным, то в первом случае будет сделана «инициализация значением» (value-initialization), а во втором — «инициализация по умолчанию» (default-initialization), и то только для non-POD типа. Инициализация значением означает вызов конструкторов по умолчанию, если они явно определены пользователем, а если не определены — обнуление всех членов. Инициализация — это вызов конструкторов по умолчанию, какими бы они не были: сгенерированы компилятором или определены пользователем. При этом сгенерированные компилятором конструкторы ничего сами не обнуляют. Очевидно, инициализация по умолчанию будет быстрее. Подробнее о разных видах инициализации можно почитать в разделе 8.5.5 стандарта C++03 / С++11.
В более старом C++98 нет понятия value-initialization, поэтому «new T()» будет обнулять только POD-типы (если верить этому).
Кстати, та же самая штука со скобками справедлива не только для new, но и для локальных переменных на стеке. Например:
int i1; // i1 == garbageНо вот так будет не совсем верно:
int i2(); // i2 == 0? wrong!Переменная i2 трактуется как функция без аргументов, возвращающая int.