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

1 ... 171 172 173 [ 174 ] 175 176 177 ... 395


stackExcp.h

class popCnEmpty { /* ... */ };

заголовочный файл stackExcp.h:

class pushCnFull { /* ... */ };

В главе 19 исключения в виде классов обсуждаются более подробно, там же рассматривается иерархия таких классов, предоставляемая стандартной библиотекой

C++.

Затем надо изменить определения функций-членов pop() и push() так, чтобы они возбуждали эти исключения. Для этого предназначена инструкция throw, которая во многих отношениях напоминает return. Она состоит из ключевого слова throw, за которым следует выражение того же типа, что и тип возбуждаемого исключения. Как

увы, это не совсем правильно

выглядит инструкция throw для функции pop() ? Попробуем такой вариант:

throw popCnEmpty;

К сожалению, так нельзя. Исключение - это объект, и функция pop() должна генерировать объект класса соответствующего типа. Выражение в инструкции throw не может быть просто типом. Для создания нужного объекта необходимо вызвать

инструкция является вызовом конструктора

конструктор класса. Инструкция throw для функции pop() будет выглядеть так:

throw popCnEmpty();

Эта инструкция создает объект исключения типа popCnEmpty.

Стек реализован на основе вектора из элементов типа int. При создании объекта класса iStack его конструктор создает вектор из int, размер которого (максимальное число элементов, хранящихся в стеке) задается с помощью начального значения. Например, следующая инструкция создает объект myStack, который способен содержать не более 20 элементов типа int:

iStack myStack(20);

При манипуляциях с объектом myStack могут возникнуть две ошибки:

запрашивается операция pop(), но стек пуст;

запрашивается операция push(), но стек полон.

Вызвавшую функцию нужно уведомить об этих ошибках посредством исключений. С чего же начать?

Во-первых, мы должны определить, какие именно исключения могут быть возбуждены. В C++ они чаще всего реализуются с помощью классов. Хотя в полном объеме классы будут нредставлены в главе 13, мы все же определим здесь два из них, чтобы использовать их как исключения для класса iStack. Эти определения мы поместим в



class iStack { public:

...

больше не возвращают значения void pop( int &value ); void push( int value );

private:

...

что эти функции-члены имеют тип void:

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

#include stackExcp.h

void iStack::pop( int &top value ) {

if ( empty() )

throw popCnEmpty(); top value = stack[ - top ];

cout << iStack::pop(): << top value << endl;

void iStack::push( int value ) {

cout << iStack::push( << value << )\n ;

if ( full() )

throw pushCnFull( value ); stack[ top++ ] = value;

представим новые реализации функций-членов pop() и push() класса iStack:

Хотя исключения чаще всего представляют собой объекты типа класса, инструкция throw может генерировать объекты любого типа. Например, функция mathFunc() в следующем примере возбуждает исключение в виде объекта-перечисления . Это корректный код C++:

Напомним, что функции-члены pop() и push() были определены как возвращающие значение типа bool: true означало, что операция завершилась успешно, а false - что произошла ошибка. Поскольку теперь для извещения о неудаче pop() и push() используют исключения, возвращать значение необязательно. Поэтому мы будем считать,



enum EHstate { noErr, zeroCp, negativeCp, severeError };

int mathFunc( int i ) { if ( i == 0 )

throw zeroCp; / / искчение в виде объекта-перечисления в противном случае продолжается нормальная обработка

Упражнение 11.1

Какие из приведенных инструкций throw ошибочны? Почему? Для правильных

(a) class exceptionType { }; throw exceptionType();

(b) int excpCbj;

throw excpCbj;

(c) enum mathErr { overflow, underflow, zeroDivide }; throw mathErr zeroDivide();

(d) int *pi = excpCbj;

инструкций укажите тип возбужденного исключения:

throw pi;

Упражнение 11.2

У класса IntArray, определенного в разделе 2.3, имеется функция-оператор operator[]() , в которой используется assert() для извещения о том, что индекс вышел за пределы массива. Измените определение этого оператора так, чтобы в подобной ситуации он генерировал исключение. Определите класс, который будет употребляться как тип возбужденного исключения.

11.2. try-блок

В нашей программе тестируется определенный в предыдущем разделе класс iStack и его функции-члены pop() и push() . Выполняется 50 итераций цикла for. На каждой итерации в стек помещается значение, кратное 3: 3, 6, 9 и т.д. Если значение кратно 4 (4, 8, 12...), то выводится текущее содержимое стека, а если кратно 10 (10, 20, 30...), то с вершины снимается один элемент, после чего содержимое стека выводится снова. Как нужно изменить функцию main() , чтобы она обрабатывала исключения, возбуждаемые функциями-членами класса iStack?



1 ... 171 172 173 [ 174 ] 175 176 177 ... 395

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