|
Программирование >> Инициализация объектов класса, структура
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:
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |