// exception5.cpp By: Aiman Hanna - ©1993-2006 Aiman Hanna // This program introduces one of the exception-handling features, the // Catch-All Handler. The program uses this feature to eliminate errors // such as the one that exception4.cpp has. // The Catch-All Handler has a declaration of the form (...), where // the three dots are referred to as an ellipsis. This catch clause is // entered for any type of exception. If the catch(...) clause is used // in combination with other catches, then it must always be placed last // in the list of exception handlers. // The Catch-All Handler is used when one wish to perform some action // as a result of throwing an exception even if the exception can not be // handled. It can also be used to indicate that an un-handled exception // has been thrown. // Key Points: 1) The Catch-All Handler #include "exception4.h" ProducerConsumer::ProducerConsumer() { for (int i = 0; i < 10; i++) buff[i] = -1; } bool ProducerConsumer::isEmpty() { if (buff[0] == -1) return true; return false; } bool ProducerConsumer::isFull() { if (buff[9] != -1) return true; return false; } void ProducerConsumer::produceItem( int item ) { if (isFull()) throw ProduceOnFull(); // Not "throw ProduceOnFull;" if ( item == -1 ) throw ProduceInvalidValue(); int i = 0; while (buff[i++] != -1); buff[i - 1] = item; } void ProducerConsumer::consumeItem( ) { if (isEmpty()) throw ConsumeOnEmpty(); int i = 0, item = -1; while ( (i < 10) && (buff[i] != -1) ) i++; item = buff[i-1]; buff[i-1] = -1; } void ProducerConsumer::setItem(int item) { produceItem( item ); } void ProducerConsumer::displayBuffContents() { cout << "\nThe buffer contents at this point are: " << endl; for (int i= 0; i < 10; i++) cout << buff[i] << " "; cout << endl << endl; } void Excp::showExcpMessage() { cerr << "An exception has occurred" << endl; } void ProducerConsumerExcp::showExcpMessage() { cerr << "A producer-consumer exception has occurred" << endl; } void ConsumeOnEmpty::showExcpMessage() { cerr << "An exception has occurred: Trying to consume from an empty buffer" << endl; } void ProduceOnFull::showExcpMessage() { cerr << "An exception has occurred: Trying to produce to a full buffer" << endl; } void ProduceInvalidValue::showExcpMessage() { cerr << "An exception has occurred: Trying to produce an invalid value" << endl; } int main() { ProducerConsumer pc1; try{ pc1.consumeItem( ); } catch (ConsumeOnEmpty coe) { coe.showExcpMessage(); } // Try to produce more items than the buffer can hold // Notice what happens when the exception is thrown try { for (int i = 0; i < 13; i++) { if ( i == 9 ) pc1.produceItem (-1); // Attempt to produce an invalid value pc1.produceItem(i * 5); // i*5 is just a value } } catch (ProduceOnFull pof) { pof.showExcpMessage(); } catch ( ... ) { cerr <<"Your program has thrown an exception, but this exception does not seem to be handled."; cerr << " Check your code again." << endl; } pc1.displayBuffContents(); // try to consume more items than what the buffer has try { for (int i = 0; i < 13; i++) { pc1.consumeItem(); if ((i == 7) || (i ==8) || (i ==9)) // display the contents just before the pc1.displayBuffContents(); // exception should occur } } catch (ConsumeOnEmpty coe) { coe.showExcpMessage(); } catch ( ... ) { cerr <<"Your program has thrown an exception, but this exception does not seem to be handled."; cerr << " Check your code again." << endl; } return 0; } // The result of running the program /* An exception has occurred: Trying to consume from an empty buffer Your program has thrown an exception, but this exception does not seem to be handled. Check your code again. The buffer contents at this point are: 0 5 10 15 20 25 30 35 40 -1 The buffer contents at this point are: 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 The buffer contents at this point are: -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 An exception has occurred: Trying to consume from an empty buffer */