Поведение, которое вы видите, хорошо определено для вашего класса.
Как и почему поведение четко определено?
Правило:
Если вы не предоставляете конструктор без аргументов, компилятор генерирует его для вашей программы на тот случай, если он нужен вашей программе.
Оговорка:
Компилятор не создает конструктор без аргументов, если ваша программа определяет для класса любой конструктор.
Согласно стандарту C ++ объект может быть инициализирован тремя способами:
- Нулевая инициализация
- Инициализация по умолчанию &
- Значение Инициализация
Когда за именем типа или инициализатором конструктора следует ()
, инициализация происходит посредством инициализации значения.
Таким образом,
date any =date();
^^^
Значение Инициализирует безымянный объект и затем копирует его в локальный объект any
,
пока:
date any;
будет Инициализация по умолчанию .
Значение Initialization дает начальное значение ноль для членов, которые находятся вне досягаемости любого конструктора.
В вашей программе n
и m
недоступны для любого конструктора и, следовательно, инициализируются как 0
.
Ответ на отредактированный вопрос:
В вашем отредактированном случае ваш класс предоставляет конструктор без аргументов date()
, который способен (и должен) инициализировать элементы n
и m
, но этот конструктор не инициализирует оба члена, поэтому в этом случае нет Происходит нулевая инициализация, и неинициализированные элементы в объекте имеют значение Indeterminate (любое случайное), далее этот временный объект копируется в объект any
, который отображает показанные неопределенные значения элементов.
Для фанатов Standerdese:
Правила для инициализации объекта точно определены в:
C ++ 03 Стандарт 8.5 / 5:
К инициализации нулями объект типа T означает:
- если T - скалярный тип (3.9), объекту присваивается значение 0 (ноль), преобразованное в T;
- если T является типом класса, не являющимся объединением, каждый элемент нестатических данных и каждый подобъект базового класса инициализируются нулями;
- если T является типом объединения, первый именованный элемент данных объекта инициализируется нулями;
- если T является типом массива, каждый элемент инициализируется нулями;
- если T является ссылочным типом, инициализация не выполняется.
К default-initialize объект типа T означает:
- если T является типом класса, отличным от POD (раздел 9), вызывается конструктор по умолчанию для T (и инициализация является некорректной, если у T нет доступного конструктора по умолчанию);
- если T является типом массива, каждый элемент инициализируется по умолчанию;
- иначе объект инициализируется нулями.
К значение-инициализация объект типа T означает:
- если T является типом класса (раздел 9) с конструктором, объявленным пользователем (12.1), то вызывается конструктор по умолчанию для T (и инициализация некорректна, если у T нет доступного конструктора по умолчанию);
- если T является типом класса без объединения без конструктора, объявленного пользователем, то каждый нестатический член данных и компонент базового класса T инициализируется значением;
- если T является типом массива, то каждый элемент инициализируется значением;
- иначе объект инициализируется нулями