Алекс Jenter - Программирование на Visual C++. Архив рассылки
- Название:Программирование на Visual C++. Архив рассылки
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Алекс Jenter - Программирование на Visual C++. Архив рассылки краткое содержание
РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ ПРОЕКТА RSDN, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, ПОЛНЫЙ АРХИВ ПРЕДЫДУЩИХ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.
Программирование на Visual C++. Архив рассылки - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Это все на сегодня. Счастливо!
Алекс Jenter jenter@mail.ru Красноярск, 2001.Программирование на Visual C++
Выпуск №39 от 1 апреля 2001 г.
Добрый день, уважаемые подписчики! С праздником вас!
СТАТЬЯ
Диагностические средства MFC
Автор: Олег Быков
Библиотека MFC предоставляет программисту мощный набор средств для отладки приложений любой сложности. Данная статья ставит своей целью последовательное рассмотрение диагностических средств для помощи начинающим MFC-программистам в выборе и более полном их использовании.
Разработка коммерческих приложений всегда подразумевает написание стабильно работающих систем, и, как следствие, наличие в коде тотальной проверки всего на свете – входных параметров функций, возвращенных значений, полученных указателей и т.д. Но за стабильность приходится платить замедлением работы программы. MFC предлагает следующий подход к проблеме: разработчик вставляет в код набор диагностических макроопределений, которые при невыполнении заданных условий сообщают имя исходного файла с ошибкой, номер строки, и останавливают работу программы. При этом данные макроопределения выполняются только при отладочной сборке проекта (Debug build).
Иными словами, в код помещаются проверки, которые выполняются только в отладочной версии программы, и не включаются в код при окончательной сборке (Release build). За время работы с отладочной версией программы (в идеале) выясняются и устраняются все возможные ошибочные ситуации и надобность в замедляющих работу проверках отпадает (здесь не имеются в виду ошибки, на которые программа должна реагировать определенными действиями. В частности, не стоит проверять таким образом результаты работы API-функций, так как нельзя гарантировать корректность возвращаемых ими значений и в отладочной сборке, и в окончательной). Чтобы стало понятней, рассмотрим несколько диагностических макроопределений.
ASSERT и VERIFYASSERT – пожалуй, один из самых часто употребляемых макросов. Принимая в качестве аргумента булево значение, ASSERT продолжает работу программы, если это значение равно TRUE, и прерывает работу программы в ином случае. При этом ASSERT выводит информационное окно с именем исходного файла и номером строки, содержащей сработавший макрос, и предоставляет разработчику выбор – окончательно прервать работу программы (Abort), переключиться в окно отладчика (Retry) или продолжить работу (Ignore).
В качестве примера использования ASSERT можно привести проверку входного значения функции:
void CPerson::SetPersonAge(int nAge) {
ASSERT((nAge>=0) && (nAge<200)); // сработает при любых x, меньших 0
m_nAge = x; // или больших 199
}
При срабатывании макроса (то есть, при передаче неверного nAge) у разработчика есть возможность переключиться в окно отладчика и через список вызовов (Call Stack) определить, откуда был передан ошибочный параметр.
ПРИМЕЧАНИЕ
ASSERT развернется в код только при Debug-сборке. Чтобы обеспечить вычисление параметра и в окончательной версии проекта (в случае, когда в ASSERT вызывается нужная функция), используйте макроопределение VERIFY. При Debug-сборке этот макрос полностью идентичен ASSERT, но, в отличие от него, при Release-сборке VERIFY разворачивается в код и вычисляет значение своего аргумента, хотя при этом никак не влияет на ход выполнения программы.
В MFC определен вспомогательный макрос DEBUG_ONLY, который служит для обеспечения выполнения своего параметра только при Debug-сборке. В Release-версии приложения выражение внутри DEBUG_ONLY будет проигнорировано.
ASSERT_KINDOF и ASSERT_VALIDЭти макросы предназначены для диагностики состояния объектов. ASSERT_KINDOF принимает два параметра — имя класса и указатель на объект - и срабатывает (прерывая выполнение программы подобно ASSERT) в случае, когда объект, переданный по указателю, не является объектом данного класса или одного из потомков данного класса. Пример использования макроса:
CPerson::CPerson(CPerson &newPerson) {
ASSERT_KINDOF(CPerson, &newPerson); // сработает, если в конструктор
// был передан объект не того класса
}
ASSERT_KINDOF полностью идентичен следующей конструкции (для нашего примера):
ASSERT(newPerson.IsKindOf(RUNTIME_CLASS(CPerson)));
Для того, чтобы получить информацию о классе в процессе исполнения, этот класс должен быть унаследован от CObject (или одного из его потомков), и для него должны быть использованы макросы DECLARE_DYNAMIC(classname) и IMPLEMENT_DYNAMIC(classname, baseclass) (иначе обращение к ASSERT_KINDOF приведет к ошибке нарушения защиты). Это относится и к проверяемому объекту, и к классу.
ASSERT_VALID служит для проверки внутреннего состояния объектов. Этот макрос принимает один параметр – указатель на проверяемый объект – и проделывает с ним следующее: проверяет валидность указателя, проверяет его на равенство NULL, и вызывает функцию объекта AssertValid.
AssertValid реализована почти во всех классах MFC (унаследованных от CObject), но разработчик может реализовать ее и в своем классе, соблюдая определенные правила. Во-первых, AssertValid должна быть переопределенной виртуальной функцией класса CObject. Эта функция описана как const, поэтому внутри нее нельзя изменять данные класса. Во-вторых, для индикации факта невалидности объекта функция должна использовать макрос ASSERT. И в-третьих, в AssertValid желательно вызвать эту же функцию класса-родителя.
Таким образом, разработчик может использовать ASSERT_VALID для реализации любых алгоритмов проверки состояния объекта. Например, вот так:
void CPerson::AssertValid() const {
CObject::AssertValid(); // подразумевается, что CPerson унаследован
// от CObject
ASSERT((m_nAge>=0) && (m_nAge<200));
}
ПРИМЕЧАНИЕ
ASSERT_KINDOF и ASSERT_VALID развернутся в код только при Debug-сборке.
В MFC определены два вспомогательных макроса для тестирования указателей: ASSERT_POINTER и ASSERT_NULL_OR_POINTER. Оба они принимают в качестве параметров два значения — указатель и его тип. ASSERT_POINTER сначала проверяет указатель на NULL, затем тестирует память по этому указателю на валидность. По непрохождении хотя бы одной проверки макрос срабатывает и останавливает работу программы. ASSERT_NULL_OR_POINTER также проверяет память, на которую ссылается указатель, но не прерывает выполнение программы, если тестируемый указатель равен NULL (хотя указатель при этом и является невалидным).
При отладке приложений у разработчика часто возникает необходимость узнать значение какой-нибудь переменной или результат, возвращенный функцией. Для этого используют либо пошаговое исполнение интересующего участка кода с просмотром переменных в Watch-окне отладчика, либо вывод информации с помощью информационных окон (функции MessageBox и AfxMessageBox).
Читать дальшеИнтервал:
Закладка: