![]() |
|
Программирование >> Инициализация объектов класса, структура
class iStack { public: public: void pop( int &value ) throw(popCnEmpty); void push( int value ) throw(pushCnFull); void push( int value private: ... добавив спецификации исключений: Гарантируется, что при обращении к pop() не будет возбуждено никаких исключений, кроме popCnEmipty, а при обращении к push()- только pushCnFull. Объявление исключения - это часть интерфейса функции, оно должно быть задано при ее объявлении в заголовочном файле. Спецификация исключений - это своего рода контракт между функцией и остальной частью программы, гарантия того, что функция не будет возбуждать никаких исключений, кроме перечисленных. Если в объявлении функции присутствует спецификация исключений, то при повторном объявлении этой же функции должны быть перечислены точно те же типы. Спецификации исключений в разных объявлениях одной и той же функции не два объявления одной и той же функции extern int foo( int = 0 ) throw(string); ошибка: опущена спецификация исключений суммируются: extern int foo( int parm ) { } Что произойдет, если функция возбудит исключение, не перечисленное в ее спецификации? Исключения возбуждаются только при обнаружении определенных аномалий в поведении программы, и во время компиляции неизвестно, встретится ли то или иное исключение во время выполнения. Поэтому нарушения спецификации исключений функции могут быть обнаружены только во время выполнения. Если функция возбуждает исключение, не указанное в спецификации, то вызывается unexpected() из стандартной библиотеки C++, а та по умолчанию вызывает terminate() . (В некоторых случаях необходимо переопределить действия, выполняемые функцией unexpected() . Стандартная библиотека предоставляет механизм для этого. Подробнее см. [STRAUSTRUP97].) Необходимо уточнить, что unexpected() не вызывается только потому, что функция возбудила исключение, не указанное в ее спецификации. Все нормально, если она обработает это исключение самостоятельно, внутри функции. Например: исключения, которые она может возбуждать. При этом гарантируется, что другие исключения функция возбуждать не будет. Такая спецификация следует за списком формальных параметров функции. Она состоит из ключевого слова throw, за которым идет список типов исключений, заключенный в скобки. Например, объявления функций-членов класса iStack можно модифицировать, void recoup( int op1, int op2 ) throw(ExceptionType) { try { ... throw string( were in control ); обрабатывается возбужденное искчение catch ( string ) { сделать все необходимое } все хорошо, unexpected() не вызается Функция recoup() возбуждает исключение типа string, несмотря на его отсутствие в спецификации. Поскольку это исключение обработано в теле функции, unexpected() не вызывается. Нарушения спецификации исключений функции обнаруживаются только во время выполнения. Компилятор не сообщает об ошибке, если в выражении throw возбуждается исключение неуказанного типа. Если такое выражение никогда не выполнится или не возбудит исключения, нарушающего спецификацию, то программа будет работать, как и extern void doit( int, int ) throw(string, exceptionType); void action ( int op1, int op2 ) throw(string) { doit( op1, op2 ); ошибки компиляции не будет ... ожидалось, и нарушение никак не проявится: doit() может возбудить исключение типа exceptionType, которое не разрешено спецификацией action() . Однако функция компилируется успешно. Компилятор при этом генерирует код, гарантирующий, что при возбуждении исключения, нарушающего спецификацию, будет вызвана библиотечная функция unexpected() . Пустая спецификация показывает, что функция не возбуждает никаких исключений: extern void no problem () throw(); Если же в объявлении функции спецификация исключений отсутствует, то может быть возбуждено исключение любого типа. Между типом возбужденного исключения и типом исключения, указанного в int convert( int parm ) throw(string) { ... if ( somethingRather ) ошибка программы: / / convert() не допускает искчения типа const char* throw help! ; спецификации, не разрешается проводить никаких преобразований: extern void (*pf) ( int ) throw(string); ошибка: отсутствует спецификация искчения суммируются, они должны быть одинаковыми: void (*pf)( int ); При работе с указателем на функцию со спецификацией исключений есть ограничения на тип указателя, используемого в качестве инициализатора или стоящего в правой части присваивания. Спецификации исключений обоих указателей не обязаны быть идентичными. Однако на указатель-инициализатор она должна накладывать столь же или более строгие ограничения, чем на инициализируемый указатель (или тот, которому void recoup( int, int ) throw(exceptionType); void no problem() throw(); void doit( int, int ) throw(string, exceptionType); правильно: ограничения, накладываемые на спецификации исключений recoup() и pf1, одинаковы void (*pf1)( int, int ) throw(exceptionType) = &recoup; правильно: ограничения, накладываемые на спецификацию исключений no problem(), более строгие, чем для pf2 void (*pf2)( ) throw(string) = &no problem; ошибка: ограничения, накладываемые на спецификацию исключений doit(), менее строгие, чем для pf3 присваивается значение). Например: void (*pf3)( int, int ) throw(string) = &doit; Выражение throw в функции convert() возбуждает исключение типа строки символов в стиле языка C. Созданный объект-исключение имеет тип const char*. Обычно выражение типа const char* можно привести к типу string. Однако спецификация не допускает преобразования типов, поэтому если convert() возбуждает такое исключение, то вызывается unexpected() . Для исправления ошибки выражение throw можно модифицировать так, чтобы оно явно преобразовывало значение выражения в тип string: throw string( help! ); 11.4.1. Спецификации исключений и указатели на функции Спецификацию исключений можно задавать и при объявлении указателя на функцию. Например: void (*pf)( int ) throw(string); В этом объявлении говорится, что pf указывает на функцию, которая способна возбуждать только исключения типа string. Как и для объявлений функций, спецификации исключений в разных объявлениях одного и того же указателя не
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0.083
При копировании материалов приветствуются ссылки. |