Программирование >>  Инициализация объектов класса, структура 

1 ... 17 18 19 [ 20 ] 21 22 23 ... 395


ostreams operator (ostream &os,const Example2<elemType> &ex)

(a) Examiple2<Array<int>*> ex1;

(b) exl.miin (&ex1);

(c) Examiple2<int> sa(1024),sb;

(d) sa = sb;

(e) Examiple2<string> exs( Walden );

Какие действия вызывают следующие инструкции?

(f) cout << exs: << exs << endl; Упражнение 2.16

Пример из предыдущего упражнения накладывает определенные ограничения на типы данных, которые могут быть подставлены вместо elemType. Так, параметр конструктора имеет по умолчанию значение 0:

explicit Example2 (elemType val=0) : val(val) {};

Однако не все тин1 могут быть инициализированы нулем (например, тин string), поэтому определение объекта

Example2<string> exs( Walden );

является правильным, а

Example2<string> exs2;

приведет к синтаксической ошибке4. Также ошибочным будет вызов функции min() , если для данного тина не определена операция меньше. С++ не позволяет задать ограничения для типов, подставляемых в шаблоны. Как вы думаете, было бы полезным иметь такую возможность? Если да, попробуйте придумать синтаксис задания ограничений и перепишите в нем определение класса Example2. Если нет, поясните почему.

Упражнение 2.17

Как было показано в предыдущем упражнении, попытка использовать шаблон Example2 с типом, для которого не определена операция меньше, приведет к синтаксической ошибке. Однако ошибка проявится только тогда, когда в тексте компилируемой программы действительно встретится вызов функции min() , в противном случае компиляция пройдет успешно. Как вы считаете, оправдано ли такое поведение? Не лучше ли предупредить об ошибке сразу, при обработке описания шаблона? Поясните свое мнение.

4 Вот как выглядит общее решение этой проблемы:

Example2( elemType nval = elemType() ) val( nval ) {}

reams operator (ostream & ex.print(os); return os;



if ( !infile ) {

string errMsg( Невозможно открыть файл: ); errMsg += fileName; throw errMsg;

случае невозможности открыть некоторый файл выглядит следующим образом:

Место программ!, в котором исключение обрабатывается. При возбуждении исключения нормальное выполнение программы приостанавливается и управление передается обработчику исключения. Поиск нужного обработчика часто включает в себя раскрутку так называемого стека вызовов программы. После обработки исключения выполнение программы возобновляется, но не с того места, где произошло исключение, а с точки, следующей за обработчиком. Для определения обработчика исключения в С++ используется ключевое слово catch. Вот как может выглядеть обработчик для примера из предыдущего абзаца:

catch (string exceptionMsg) { log message (exceptionMsg); return false;

Кажд1й catch-обработчик ассоциирован с исключениями, возникающими в блоке операторов, который непосредственно предшествует обработчику и помечен ключевым словом try. Одному try-блоку могут соответствовать несколько catch-предложений,

int* stats (const int *ia, int size) каждое из которых относится к определенному виду исключений. Приведем пример:

int *pstats = new int [4];

2.6. Использование исключений

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

С++ предоставляет стандартн1й способ реакции на исключения. Благодаря вынесению в отдельную часть программы кода, ответственного за проверку и обработку ошибок, значительно облегчается восприятие текста программа: и сокращается ее размер. Единый синтаксис и стиль обработки исключений можно, тем не менее, приспособить к самым разнообразным нуждам и запросам.

Механизм исключений делится на две основные части:

точка программы, в которой произошло исключение. Определение того факта, что при выполнении возникла какая-либо ошибка, влечет за собой возбуждение исключения. Для этого в С++ предусмотрен специальный оператор throw. Возбуждение исключения в



try {

pstats[0] = sum it (ia,size); pstats[1] = min val (ia,size); pstats[2] = max val (ia,size);

catch (string exceptionMsg) { код обработчика

catch (const statsException SstatsExcp) { код обработчика

pstats [3] = pstats[0] / size; do something (pstats);

return pstats;

В данном примере в теле функции stats() три оператора заключена: в try-блок, а четыре - нет. Из этих четырех операторов два способны возбудить исключения.

1)int *pstats = new int [4];

Выполнение оператора new может окончиться неудачей. Стандартная библиотека С++ предусматривает возбуждение исключения bad alloc в случае невозможности выделить нужное количество памяти. Поскольку в примере не предусмотрен обработчик исключения bad alloc, при его возбуждении выполнение программы закончится аварийно.

2) do something (pstats);

Mi не знаем реализации функции do something(). Любая инструкция этой функции, или функции, вызванной из этой функции, или функции, вызванной из функции, вызванной этой функцией, и так далее, потенциально может возбудить исключение. Если в реализации функции do something и вызываемых из нее предусмотрен обработчик такого исключения, то выполнение stats() продолжится обычным образом. Если же такого обработчика нет, выполнение программы аварийно завершится.

Необходимо заметить, что, хотя оператор

pstats [3] = pstats[0] / size;

может привести к делению на ноль, в стандартной библиотеке не предусмотрен такой тип исключения.

Обратимся теперь к инструкциям, объединенным в try-блок. Если в одной из вызываем1х в этом блоке функций - sum it(), min val() или max val() -произойдет исключение, управление будет передано на обработчик, следующий за try-блоком и перехватывающий именно это исключение. Ни инструкция, возбудившая исключение, ни следующие за ней инструкции в try-блоке выполнены не будут. Представим себе, что при вызове функции sum it() возбуждено исключение:

throw string ( Сшибка: adump27832 );

Выполнение функции sum it() прервется, операторы, следующие в try-блоке за вызовом этой функции, также не будут выполнены, и pstats[0] не будет инициализирована. Вместо этого возбуждается исключительное состояние и исследуются два catch- обработчика. В нашем случае в1нолняется catch с параметром тина string:



1 ... 17 18 19 [ 20 ] 21 22 23 ... 395

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика