Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Cpp_C7.docx
Скачиваний:
6
Добавлен:
07.09.2019
Размер:
44.97 Кб
Скачать

Семинар 7. Исключения. Потоки ввода-вывода. Пространства имен.

1. Исключения

Рассмотрим следующий пример функции meang, возвращающей среднее гармоническое двух чисел

double meang(double x, double y)

{

return 2.*x*y/(x+y);

}

В большинстве случаев эта функция будет работать правильно. Однако, в отдельных «исключительных» случаях возникает ошибка – в данном случае деление на ноль при x=-y. Такого рода события получили название «исключение». В языке Си++ существуют специальные средства обработки исключений. Эта обработка включает три этапа:

  • генерация исключения (throw);

  • использование блока try{} в том месте программы, где может произойти исключение;

  • собственно обработка исключения в блоке catch{}.

Вот как это может быть реализовано:

int main()

{

double x,y;

cin >> x;

cin >> y;

try

{

x = meang(x,y);

}

catch (char *s)

{

cout << s;

exit (0);

}

cout << x;

}

double meang(double x, double y)

{

if (x == -y) throw "деление на ноль";

return 2.*x*y/(x+y);

}

В данном случае исключение генерируется в функции meang при наступлении соответствующих условий. При этом оператор throw «вбрасывает» указатель на строку. В основной функции в блок try помещается вызов функции meang, т.к. именно в ней может произойти исключение. К блоку try должен примыкать один или несколько блоков обработки исключений catch. Обработка исключения произойдет в том блоке, тип аргумента которого совпадет с типом генерируемого исключения.

В отсутствие исключения внутри блока try управление блоку catch не передается (он пропускается). При возникновении исключения логика программы следующая. Оператор throw, сгенерировав исключение, обеспечивает поиск ближайшего блока try, внутри которого это исключение произошло. В примере этот блок находится в вызывающей функции. Управление передается в соответствующий блок catch с нужным типом аргумента. Оставшиеся операторы в блоке try не выполняются.

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

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

double meang(double , double) throw (char*);

2. Пространство имен

Язык Си++ позволяет использовать одинаковые имена (функций, переменных, классов …) ограничив область их видимость по умолчанию именованным пространством. Такое пространство называется пространством имен. Для его обозначения используется блок с ключевым словом namespace. Например, мы могли бы определить функцию meang в пользовательском пространстве MyNameSpace:

namespace MyNameSpace

{

double meang(double x, double y)

{

if (x == -y) throw "деление на ноль";

return 2.*x*y/(x+y);

}

}

Тогда при вызове этой функции из другого пространства имен (в том числе, глобального пространства имен по умолчанию) имя этой функции следует употреблять c соответствующим спецификатором доступа:

x = My1::meang(x,y);

Чтобы не делать это каждый раз, можно использовать оператор using:

using My1::meang;

x = meang(x,y);

Чтобы сделать все имена из пространства имен My1 доступными по умолчанию, используется директива

using namespace My1;

Многие стандартные объекты, такие как cout или cin определены в стандартном пространстве имен std. Поэтому для их использования применяют операторы

using std::cin;

using std::cout;

или директиву

using namespace std;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]