Кроме того, многие программисты считают, что использование исключений не по прямому назначению делает программу слишком запутанной и нелогичной.
Всегда ли следует перехватывать исключения сразу за блоком try, генерирующим это исключение?
Нет, в стеке вызовов перехват исключения может осуществляться в любом месте, после чего стек вызовов будет пройден то того места, где происходит обработка исключения.
Зачем использовать утилиту отладки, если те же функции можно осуществлять прямо во время компиляции с помощью объекта cout и условного выражения #ifdef debug?
В действительности утилита отладки предоставляет значительно больше средств и возможностей, таких как пошаговое выполнение программы, установка точек останова и анализ текущих значений переменных. При этом вам не приходится перегружать свой код многочисленными командами препроцессора и выражениями, которые никак не связаны с основным назначением программы.
В этом разделе предлагаются вопросы для самоконтроля и укрепления полученных знаний, а также ряд упражнений, которые помогут закрепить ваши практические навыки. Попытайтесь самостоятельно ответить на вопросы теста и выполнить задания, а потом сверьте полученные результаты с ответами в приложении Г. Не приступайте к изучению материала следующей главы, если для вас остались неясными хотя бы некоторые из предложенных ниже вопросов.
1. Что такое исключение?
2. Для чего нужен блок try?
3. Для чего используется оператор catch?
4. Какую информацию может содержать исключение?
5. Когда создается объект исключения?
6. Следует ли передавать исключения как значения или как ссылки?
7. Будет ли оператор catch перехватывать производные исключения, если он настроен на базовый класс исключения?
8. Если используются два оператора catch, один из которых настроен на базовое сообщение, а второй — на производное, то в каком порядке их следует расположить?
9. Что означает оператор catch(...)?
10. Что такое точка останова?
1. Запишите блок try и оператор catch для отслеживания и обработки простого исключения.
2. Добавьте в исключение, полученное в упражнении 1, переменную-член и метод доступа и используйте их в блоке оператора catch.
3. Унаследуйте новое исключение от исключения, полученного в упражнении 2. Измените блок оператора catch таким образом, чтобы в нем происходила обработка как производного, так и базового исключений.
4. Измените код упражнения 3, чтобы получить трехуровневый вызов функции.
5. Жучки: что не правильно в следующем коде?
#include "string" //класс строк
сlass xOutOfMemory
{
public:
xOutOfMemory(){ theMsg = new сhar[20];
strcpy(theMsg, "trror in momory");}
~xOutOfMemory(){ delete [] theMsg;
cout << "Memory restored, " << endl; }
char * Message() { return theMsg; }
private:
char >> theMsg;
};
main()
{
try
{
char * var = new char;
if ( var == 0 )
{
xOutOfMemory * px = new xOutOfMemory;
throw px;
}
}
catch( xOutOfMemory * theException )
{
cout << theException->Message() <
delete theException;
}
return 0;
}
6. Данный пример содержит потенциальную ошибку, подобную возникающей при попытке выделить память для показа сообщения об ошибке в случае обнаружения нехватки свободной памяти. Вы можете протестировать эту программу, изменив строку if (var == 0) на if (1), которая вызовет создание исключения.
Примите наши поздравления! Вы почти завершили изучение полного трехнедельного интенсивного курса введения в C++. К этому моменту у вас должно быть ясное понимание языка C++, но в современном программировании всегда найдутся еще не изученные области. В этой главе будут рассмотрены некоторые опущенные выше подробности, а затем намечен курс для дальнейшего освоения C++.
Большая часть кода файлов источника представлена командами на языке C++. Компилятор превращает этот код в программу на машинном языке. Однако перед запуском компилятора запускается препроцессор, благодаря чему можно воспользоваться возможностями условной компиляции. Итак, сегодня вы узнаете:
• Что представляет собой условная компиляция и как с ней обращаться
• Как записывать макросы препроцессора
• Как использовать препроцессор для обнаружения ошибок
• Как управлять значениями отдельных битов и использовать их в качестве флагов
• Какие шаги следует предпринять для дальнейшего эффективного изучения C++
При каждом запуске компилятора сначала запускается препроцессор, который ищет команды препроцессора, начинающиеся с символа фунта (#). При выполнении любой из этих команд в текст исходного кода вносятся некоторые изменения, в результате чего создается новый файл исходного кода. Этот новый файл является временным, и вы обычно его не видите, но можете дать команду компилятору сохранить его для последующего просмотра и использования.
Читать дальше