Это означает, что ваш код должен быть подробно прокомментирован, даже если вы и не предполагаете, что кто-то другой, кроме вас, может заглянуть в него. Когда пройдет месяцев шесть после того, как вы передадите свой код заказчику, вы сами будете смотреть на свою программу глазами постороннего человека и удивляться тому, как можно было написать такой непонятный и извилистый код, надеясь при этом на успешную работу.
В C++ исключение — это объект, который передается из области кода, где возникла проблема, в ту часть кода, где эта проблема обрабатывается. Тип исключения определяет, какая область кода будет обрабатывать проблему и как содержимое переданного объекта, если он существует, может использоваться для обратной связи с пользователем. Основная идея использования исключений довольно проста.
• Фактическое распределение ресурсов (например, распределение памяти или захват файла) обычно осуществляется в программе на низком уровне.
• Выход из исключительной ситуации, возникшей при сбое операции из-за нехватки памяти или захвата файла другим приложением обычно реализуется на высоком уровне программирования в коде, описывающем взаимодействие программы с пользователем.
• Исключения обеспечивают переход от кода распределения ресурсов к коду обработки исключительной ситуации. Желательно, чтобы код обработки исключительной ситуации не только отслеживал ее появление, но и мог обеспечить элегантный выход из исключительной ситуации, например отмену выделения памяти в случае ее нехватки.
Как используются исключения
Создаются блоки try для помещения в них фрагментов кода, которые могут вызвать проблему, например:
try
{
SomeDangerousFunction();
}
Исключения, возникшие в блоках try, обрабатываются в блоках catch, например:
try
{
SomeDangerousFunction();
}
catch(OutOfMemory)
{
// предпринимаем некоторые действия
}
catch(FileNotFound)
{
// предпринимаем другие действия
}
Ниже приведены основные принципы использовании исключений.
1. Идентифицируйте те области программы, где начинается выполнение операции, которая могла бы вызвать исключительную ситуацию, и поместите их в блоки try.
2. Создайте блоки catch для перехвата исключений, если таковые возникнут, очистки выделенной памяти и информирования пользователя соответствующим образом. В листинге 20.1 иллюстрируется использование блоков try и catch.
Исключения — это объекты, которые используются для передачи информации о проблеме.
Блок try — это заключенный в фигурные скобки блок, содержащий фрагменты программы, способные вызвать исключительные ситуации.
Блок catch — это блок, который следует за блоком try и в котором выполняется обработка исключений.
При возникновении исключительной ситуации управление передается блоку catch, который следует сразу за текущим блоком try.
Примечание: Некоторые очень старые компиляторы не поддерживают обработку исключений. Однако обработка исключений является частью стандарта ANSI C++. Все современные версии компиляторов полностью поддерживают эту возможность. Если у вас устаревший компилятор, вы не сможете скомпилировать и выполнить листинги, приведенные на этом занятии. Однако все же стоит прочитать представленный материал до конца, а затем вернуться к нему после обновления своего компилятора.
Листинг 20.1. Возникновение исключительной ситуации
1: #include
2:
3: const int DefaultSize = 10;
4:
5: class Array
6: {
7: public:
8: // конструкторы
9: Array(int itsSize = DefaultSize);
10: Array(const Array &rhs);
11: ~Array() { delete [] pType;}
12:
13: // операторы
14: Array& operator=(const Array&);
15: int& operator[](int offSet);
16: const int& operator[](int offSet) const;
17:
18: // методы доступа
19: int GetitsSize() const { return itsSize; }
20:
21: // функция-друг
22: friend ostream& operator<< (ostream&, const Array&);
23:
24: class xBoundary { } ; // определяем класс исключений
25: private:
26: int *pType;
27: int itsSize;
28: };
29:
30:
31: Array::Array(intsize):
32: itsSize(size)
33: {
34: рТуре = new int[size];
35: for (int i = 0; i
36: pType[i] = 0;
37: }
38:
39:
40: Array& Array::operator=(const Array &rhs)
41: {
42: if (this == &rhs)
43: return *thts;
44: delete [] pType;
45: itsSize = rhs.GetitsSiza();
46: pType = new int[itsSize];
47: for (int i = 0; i
48: pType[i] = rhs[i];
49: return *this;
50: }
51:
52: Array::Array(const Array &rhs)
53: {
54: itsSize = rhs.GetitsSize();
55: pType = new int[itsSize];
56: for (int i = 0; i
57: pType[i] = rhs[i];
58: }
59:
60:
61: int& Array::operator[](int offSet)
62: {
63: int size = GetitsSize();
64: if (offSet >= 0 && offSet < GetitsSize())
65: return pType[offSet];
66: throw xBoundary();
67: return pType[0]; // требование компилятора
Читать дальше