|
Программирование >> Инициализация объектов класса, структура
catch (string exceptionMsg) { код обработчика После выполнения управление будет передано инструкции, следующей за последним catch- обработчиком, относящимся к данному try-блоку. В нашем случае это pstats [3] = pstats[0] / size; (Конечно, обработчик сам может возбуждать исключения, в том числе - того же типа. В такой ситуации будет продолжено выполнение catch-предложений, определенных в программе, вызвавшей функцию stats() .) catch (string exceptionMsg) { Вот пример: код обработчика cerr << stats(): исключение: << exceptionMsg << endl; delete [] pstats; return 0; В таком случае выполнение вернется в функцию, вызвавшую stats() . Будем считать, что разработчик программы предусмотрел проверку возвращаемого функцией stats() значения и корректную реакцию на нулевое значение. Функция stats() умеет реагировать на два типа исключений: string и statsException. Исключение любого другого типа игнорируется, и управление передается в вызвавшую функцию, а если и в ней не найдется обработчика, - то в функцию более высокого уровня, и так до функции miain () .При отсутствии обработчика и там, программа аварийно завершится. Возможно задание специального обработчика, который реагирует на любой тип catch (... ) { обрабатывает любое исключение, однако ему недоступен объект, переданн в обработчик в инструкции throw исключения. Синтаксис его таков: (Детально обработка исключительных ситуаций рассматривается в главах 11 и 19.) Упражнение 2.18 Какие ошибочные ситуации могут возникнуть во время выполнения следующей функции: int *alloc and init (string file name) { ifstream infile (file name) int elem cnt; infile >> elem cnt; int *pi = allocate array(elem cnt); int elem; int index=0; while (cin >> elem) pi[index++] = elem; sort array(pi,elem cnt); register data(pi); return pi; Упражнение 2.19 В предыдущем примере вызываемые функции allocate array() , sort array() и register data() могут возбуждать исключения типов noMem, int и string соответственно. Перепишите функцию alloc and init() , вставив соответствующие блоки try и catch для обработки этих исключений. Пусть обработчики просто выводят в cerr сообщение об ошибке. Упражнение 2.20 Усовершенствуйте функцию alloc and init() так, чтобы она сама возбуждала исключение в случае возникновения всех возможных ошибок (это могут быть исключения, относящиеся к вызываемым функциям allocate array() , sort array() и register data() и какими-то еще операторами внутри функции alloc and init() ). Пусть это исключение имеет тип string и строка, передаваемая обработчику, содержит описание ошибки. 2.7. Использование пространства имен Предположим, что мы хотим предоставить в общее пользование наш класс Array, разработанный в предыдущих примерах. Однако не мы одни занимались этой проблемой; возможно, кем-то где-то, скажем, в одном из подразделений компании Intel был создан одноименный класс. Из-за того что имена этих классов совпадают, потенциальные пользователи не могут задействовать оба класса одновременно, они должны выбрать один из них. Эта проблема решается добавлением к имени класса некоторой строки, идентифицирующей его разработчиков, скажем, class Cplusplus Primer Third Edition Array { ... }; Конечно, это тоже не гарантирует уникальность имени, но с большой вероятностью избавит пользователя от данной проблемы. Как, однако, неудобно пользоваться столь длинными именами! Стандарт С++ предлагает для решения проблемы совпадения имен механизм, называем1й пространством имен. Кажд1й производитель программного обеспечения может заключить свои классы, функции и другие объекты в свое собственное пространство имен. Вот как выглядит, например, объявление нашего класса Array: namespace Cplusplus Primer 3E { template <class elemType> class Array { ... }; Ключевое слово namespace задает пространство имен, определяющее видимость нашего класса и названное в данном случае Cplusplus Primer 3E. Предположим, что у нас есть классы от других разработчиков, помещенные в другие пространства имен: namespace IBM Canada Laboratory { template <class elemType> class Array { ... }; class Matrix { ... }; namespace Disney Feature AAnimation { class Point { ... }; template <class elemType> class Array { ... }; По умолчанию в программе видны объекты, объявленные без явного указания пространства имен; они относятся к глобальному пространству имен. Для того чтобы обратиться к объекту из другого пространства, нужно использовать его квалифицированное имя, которое состоит из идентификатора пространства имен и идентификатора объекта, разделенных оператором разрешения области видимости (:: ). Cplusplus Primer 3E::Array<string> text; Вот как выглядят обращения к объектам приведенных выше примеров: IBM Canada Laboratory::Matrix mat; Disney Feature Animation::Point origin(5000,5000); Для удобства использования можно назначать псевдонимы пространствам имен. Псевдоним выбирают коротким и легким для запоминания. Например: псевдонимы namespace LIB = IBM Canada Laboratory; namespace DFA = Disney Feature Animation; int main() { LIB::Array<int> ia(1024); Псевдонимы употребляются и для того, чтобы скрыть использование пространств имен. Заменив псевдоним, мы можем сменить набор задействованных функций и классов, причем во всем остальном код программы останется таким же. Исправив только одну строчку в приведенном выше примере, мы получим определение уже совсем другого массива: namespace LIB = Cplusplus Primer 3E; int main() { LIB::Array<int> ia(1024);
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |