94______________________________Часть II. Программирование на C++
Если метафорически представить себе программу в виде отеля, то вставлять отладочный код в программу после ее создания — это то же самое, что обдирать стены, чтобы вставить систему пожаротушения, автоматические выключатели и сигнализацию после того, как все покрашено, оклеено обоями и устлано коврами, что гораздо тяжелее, расточительнее и требует гораздо больше ресурсов, чем делать это своевременно.
Отладочный код, добросовестно внедряемый в плоть программы по мере ее создания, легче и тщательнее справляется со своей миссией. Без сомнения, совладать с угрожающими ситуациями или данными гораздо проще в процессе становления программы, чем месяц спустя, когда уже полным ходом идет тестирование.
Препроцессор может помочь вам привести тестовый код в порядок и упростить контроль над ним. Ранее вы видели, как надлежащим образом обрамленный директивами препроцессора отладочный код может быть легко включен в компилируемый текст или исключен из него простым определением или отменой директивы. Так одно небольшое усовершенствование позволяет добиться тех же результатов, уменьшив количестве писанины и сделав отладочный код гораздо чище и аккуратнее.
Отладочная печать
Взяв в качестве образца assert, несложно создать макрос отладочной печати, который для трассировки выполнения программы можно будет легко включать и выключать. Для выполнения этой задачи нет абсолютных путей, но мы приведем здесь один вариант, из которого вы сами сможете создать другие.
В данной конкретной реализации этого приема используется вывод на консоль (т. е. на экран). Следует подчеркнуть, что вам для вывода может потребоваться обеспечить другой путь в соответствии с интерфейсом вашей программы.
Замечание
Альтернативные устройства вывода могут осуществлять запись в текстовый файл при помощи fstreams, печать в окно сообщения с помощью элементов управления VBX или OWL и другие подходящие способы фиксации следов деятельности программ.
Можно просто совместить несколько из них в одном макроопределении и переключать режимы вывода с помощью директив препроцессора; здесь может оказаться полезной директива #elif.
Одна из реализации этого приема приведена в листинге 4.3.
Замечание
(Номера строк в листинге используются только как опорные точки, в программе их на самом деле быть не должно.