Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Объектно-ориентированное программирование на C++.pdf
Скачиваний:
61
Добавлен:
23.03.2016
Размер:
1.88 Mб
Скачать

Пример: уничтожение автоматических объектов в процессе передачи исключения в catch-блок

Базовые

1

 

сведения

2

Обобщённое

3

 

программирова-

4

ние

5

Перегрузка

6

операций

 

Исключения

7

 

Порождение

8

 

Перехват и

9

 

обработка

10

 

Спецификация

11

 

Класс exception

12

 

 

13

 

14

 

15

 

16

 

17

 

18

# include < iostream >

struct Dummy { ~ Dummy (); };

Dummy ::~ Dummy ()

{ std :: cout << "# "; }

void recur ( int n) {

 

if (n

== 0)

throw

" base of recursion ";

Dummy

d;

 

 

recur (n -1);

 

 

std :: cout <<

" should never be reached !";

}

 

 

 

int main ()

 

 

 

{

 

 

 

try {

recur (10);

} catch (...) { }

return

0;

 

 

}

 

 

 

Вывод:

# # # # # # # # # #

91 / 99

92 / 99

Перехват исключений в инициализаторах конструкторов

Базовые

сведения

Обобщённое программирова- ние

Перегрузка

операций

Исключения

Порождение

Перехват и

обработка

Спецификация

Класс exception

Напомним, что конструкторы в C++ могут иметь списки инициализаторов, в которых вызываются конструкторы объектов, расположенных в полях, и конструкторы базовых классов.

Так как конструкторы полей и базовых классов могут порождать исключения, нужно уметь эти исключения перехватывать, например, для протоколирования неудачного создания объектов в логах. Для этой цели служат специальные try-блоки, обрамляющие тело конструктора, которые синтаксически выглядят как

Класс :: Класс ( параметры_конструктора ) try

:список_инициализации

{тело_конструктора }

catch ( исключение ) { тело_обработчика_исключения }

...

Отметим, что если catch-блок не оканчивается порождением другого исключения, старое исключение не уничтожается и передаётся дальше.

Пример: перехват исключений в инициализаторах конструкторов

Базовые

1

 

сведения

2

Обобщённое

3

 

программирова-

4

ние

5

Перегрузка

6

операций

 

Исключения

7

 

Порождение

8

 

Перехват и

9

 

обработка

10

 

Спецификация

11

 

Класс exception

12

 

 

13

 

14

 

15

 

16

 

17

 

18

 

19

 

20

# include

< iostream >

 

using namespace

std ;

 

struct A

{ A( int

x );

};

struct B:

public

A {

B( int x ); };

A :: A( int

x) { if

(x

< 0) throw " negative "; }

B :: B( int x) try : A(x) { }

catch ( const char *s) { cout << "1 "; }

int main ()

{

try {

Bb ( -10);

}catch (...) { cout << " 2\ n";

}

return 0;

}

1 2

93 / 99

Спецификатор throw в заголовках функций

Базовые

сведения

Обобщённое программирова- ние

Перегрузка

операций

Как и в языке Java, в C++ можно перечислить типы исключений, которые может порождать вызов функции. Для этого после списка формальных параметров следует разместить спецификатор throw:

Исключения

Порождение

Перехват и

обработка

Спецификация

Класс exception

throw ( список типов исключений )

Семантика этого спецификатора несколько отличается от семантики соответствующей конструкции языка Java, а именно:

!вызов функции, для которой разрешённые исключения не указаны, может порождать любые исключения;

!вызов функции со спецификатором throw() не порождает никаких исключений;

!компилятор не следит за тем, какие исключения порождаются внутри функции: вместо этого неразрешённые исключения просто не могут выйти за пределы функции и приводят к аварийному завершению программы.

94 / 99