О программировании
Эта статеечка предназначена для тех, кто уже имеет представление о создании классов объектов.
Что это такое
Образно говоря, пустой объект — это структура без данных. Наложив структуру на участок оперативной памяти, мы столкнемся с тем, что там есть какие-то комбинации битов, которые могут быть как-то интерпретированы, как будто это данные. Поэтому должен быть четко определенный признак того, что объект пуст. Например, для объекта типа матрица таким признаком может служить число строк, равное 0. Если объект имеет ресурс в динамической памяти, то пустой объект содержит нулевой указатель на такой ресурс.
С прикладной точки зрения, пустой объект — это объект, объявленный в программном коде, но еще не существующий.
Деструктор, если написание его необходимо, должен приводить объект к состоянию пустого. С прикладной точки зрения, это и есть уничтожение объекта.
Конструктор по умолчанию
должен создавать именно пустой объект. Потому что именно этот конструктор применяется при объявлении переменной данного классового типа. Недопустимо, чтобы такой объект вследствие ошибки программиста стал участвовать в операциях, не будучи начинен конкретной информацией.
Если же конструктор по умолчанию создает конкретный объект с осмысленной информацией, то есть опасность, что программист по рассеянности забудет настроить объект (начинить его реальной информацией), и такой объект будет участвовать в операциях над данными. Программа может выполниться "успешно", но ее результаты не будут иметь ничего общего с истиной — и что хуже всего, это может пройти незамеченным.
Часто программисты строят конструктор по умолчанию так, чтобы он создавал объект с нулевым (в каком-то смысле) значением. Во-первых, легальное нулевое значение, как правило, ни зачем не нужно. Во вторых, такой объект подвергает программу только что описанной опасности. По мнению таких программеров, пусть лучше программа выдаст недостоверный результат, чем программист обнаружит свою ошибку.
Реакция на пустой объект
Так как выполнение операции над пустым объектом (кроме заполнения его данными, естественно) является ошибкой программиста, то это должно стать фатальной ошибкой времени выполнения. Наподобие деления на 0 в типе int или обращения по нулевому адресу. Хорошо написанная функция должна обеспечить такую ошибку в случае обнаружения пустого объекта в исходных данных.
Обычно в отладчике место ошибки находится несложно. В принципе, возможно устроить обработку исключения с указанием места ошибки и последующим завершением программы.
Корректирующие действия, вроде того, что если делитель 0, то перенесем делимое без изменений в частное, приводят к недостоверным результатам счета и только затрудняют обнаружение ошибки.
Числовые типы
С этой точки зрения объявление
double x;
должно придавать переменной х невозможное значение. Во внутреннем представлении чисел с плавающей точкой такие значения есть. Одно из них так и называется: NaN — Not a Number. К сожалению, в стандарте предусмотрено значение 0, и изменить это уже невозможно. К сожалению, арифметические операции с NaN не создают ошибку, а безмолвно выполняются с результатом NaN. Потом, распечатывая массив, мы обнаруживаем массив из "nan" и начинаем гадать, где же начало всего этого безобразия. Возможно, настройкой компилятора можно добиться генерации ошибки в случае операции с NaN, но мне это неизвестно.
В числовом типе int такие специальные значения отсутствуют. Мне как-то пришлось выделить одно значение 0x80000000 = –2147483648 для исполнения аналогичной NaN роли. Предполагалось, что пользователь не напишет в исходном коде такое значение как числовое.