Шаг 263.
Среда программирования Visual C++.
Отладка программы. Отладочные макросы MFC

    На этом шаге мы рассмотрим макросы, используемые для отладки программ.

    В MFC есть макросы, облегчающие отладку и действующие только в отладочных версиях программ. Вы уже изучили макрос TRACE и его варианты, узнали, как его можно применять для регистрации действий программы и ее состояния. На этом шаге Вы познакомитесь с некоторыми другими макросами, в том числе с ASSERT и его вариациями VERIFY и DEBUG_NEW.

    Макросом ASSERT очень удобно проверять значения переменных, не добавляя постоянного кода. Например, Вы хотите проверить указатель на ненулевое значение, прежде чем его использовать. Один из способов - добавить проверку в блоке if, как это показано в следующем коде функции. Здесь в качестве параметра функция принимает указатель на объект СButton:

void SomeFunction(CButton* pbutton)
{
  if (pbutton)
  {
    //Можно использовать указатель pbutton
    .   .   .   .   .
  }

    Несмотря на то, что такие проверки помогают избежать потенциальных проблем, их нельзя оставлять в финальной версии. Ведь код, содержащий тысячи таких блоков, неоправданно увеличится в размере и замедлит выполнение программы. Дабы избежать этого, пользуются макросом ASSERT:

void SomeFunction(CButton* pbutton) 
{
  ASSERT(pbutton);      //Проверяем, что pbutton не равен нулю
  //Можно использовать указатель pbutton
  .   .   .   .   .
}

    Если переданное макросу ASSERT выражение равно нулю, программа будет остановлена и появится системное сообщение, информирующее об ошибке. В нем предлагается несколько вариантов дальнейших действий: завершить приложение, проигнорировать ошибку или запустить программу в отладчике.

    Код для макроса ASSERT создается только в отладочной версии программы, поэтому Вы можете вставить сотни таких макросов, не волнуясь о размере финальной версии. Если же Вы хотите, чтобы проверка производилась как в отладочной, так и в финальной версии программы, то применяйте макрос VERIFY.

    ASSERT можно использовать с любым булевым выражением, например ASSERT(x<y) или ASSERT(i>10), однако существуют и его специальные варианты. Макрос ASSERT_VALID применяется только с указателями на объекты, производные от MFC-класса CObject. Он выполняет те же действия, что и ASSERT, но вдобавок вызывает функцию-член AssertValid, проверяющую сам объект.

    Макрос ASSERT_KINDOF также разрешается применять только к указателям на объект, производный от класса CObject. Он определяет, является ли этот указатель объектом заданного класса или производным от него. Например, следующая строчка кода проверяет тип указателя pDoc (указывает ли он на производный от CDocument объект):

    ASSERT_KINDOF(CMyDocument, pDoc)

    Макрос DEBUG_NEW помогает определять утечки памяти, когда оператору new не соответствует оператор delete. Он прост в использовании - в код нужно добавить только одну строчку:

    #define new DEBUG_NEW

    После этого компилятор заменяет все операторы new макросом DEBUG_NEW, а об остальном позаботится MFC. В отладочных версиях макрос DEBUG_NEW отслеживает все строки кода с оператором new. Затем программа может вызвать функцию СMemoryState::DumpAllObjectSince(), которая отображает в окне Output список операторов new вместе с именем файла и номером строки, в которых они находятся. Такая информация позволяет обнаружить утечки памяти. В конечных версиях данный макрос просто заменяется на new.

    На следующем шаге мы рассмотрим применение встроенного отладчика.




Предыдущий шаг Содержание Следующий шаг