В главе 5 мы уже столкнулись со спецификацией исключений (см. п. п. 15.4 в [1]), когда рассматривали прототипы функций new() и delete(). Спецификацию исключений можно задать в заголовке любой функции, метода, конструктора или деструктора — до сих пор мы этого не делали. Если в заголовке функции не указана спецификация исключений, считается, что функция может порождать любое исключение. Однако можно специфицировать в заголовке явный список исключений, которые функция может генерировать, например:
void fl(void) throw(const char *s, string): void f2(void) throw(ZeroDevide);
Первая функция может генерировать объекты-исключения строкового типа, вторая — объекты-исключения типа ZeroDevide.
Если в заголовке скобки спецификации исключений пустые, то считается, что функция исключений не генерирует:
void f3(void) throwQ ;
Если спецификация исключений объявлена в заголовке, то она должна быть указана и во всех прототипах. Несмотря на это, спецификация исключений не входит в прототип функции, поэтому функции с различными спецификациями исключений не считаются разными при перегрузке.
Наличие спецификации исключений тем не менее не является ограничением при реальной генерации исключений — функция может сгенерировать исключение любого типа. Однако в стандарте определено (см. п. п. 15.5.2 в [1]), что, если функция генерирует исключение, не заданное в спецификации исключений, запускается стандартная функция unexpected(), которая вызывает функцию terminate(). Это инициирует аварийное завершение программы.
ПРИМЕЧАНИЕ
К сожалению, не все компиляторы исполняют стандарт в этом пункте. Например, в справочной системе Visual C++.NET 2003 явно написано, что этот пункт стандарта не выполняется — функция unexpected() не вызывается. Однако ее разрешено вызывать явным образом. |