Это ожидаемое поведение.Существует два понятия: «инициализация по умолчанию» и «инициализация значения».Если вы не упоминаете никакой инициализатор, объект «инициализируется по умолчанию», в то время как если вы упоминаете об этом, даже как () для конструктора по умолчанию, объект «инициализируется значением».Когда конструктор определен, оба случая вызывают конструктор по умолчанию.Но для встроенных типов «инициализация значения» обнуляет память, тогда как «инициализация по умолчанию» - нет.
Поэтому, когда вы инициализируете:
Type x;
, он вызовет конструктор по умолчанию, еслипредусмотрено, но примитивные типы будут неинициализированы.Однако, когда вы упоминаете инициализатор, например
Type x = {}; // only works for struct/class without constructor
Type x = Type();
Type x{}; // C++11 only
, примитивный тип (или примитивные члены структуры) будет инициализирован VALUE.
Аналогично для:
struct X { int x; X(); };
если вы определите конструктор
X::X() {}
, член x будет неинициализирован, но если вы определите конструктор
X::X() : x() {}
, он будет инициализирован VALUE.Это относится и к new
, поэтому
new int;
должно дать вам неинициализированную память, а
new int();
должно дать вам инициализированную нулевую память.К сожалению, синтаксис:
Type x();
недопустим из-за неоднозначности грамматики, а
Type x = Type();
обязан вызывать конструктор по умолчанию , за которым следует конструктор копирования , если онии указанный, и не встроенный.
C ++ 11 вводит новый синтаксис,
Type x{};
, который можно использовать в обоих случаях.Если вы все еще придерживаетесь более старого стандарта, поэтому существует Boost.ValueInitialized, так что вы можете правильно инициализировать экземпляр аргумента шаблона.
Более подробное обсуждение можно найти, например, в документации Boost.ValueInitialized * 1043.*.