Welcome to CAVI, the Cisco Academy for the Vision Impaired. Course Fees Linux Wiki HTML Wiki Documentation Index PmWiki FAQ |
Chapter77.1.1Image 1: This image shows an example of a simple program with some errors. The code has been written out below. #include <iostream> using namespace std; int main(void) { float a, b; cin >> a; cin >> b; cout<< a / b <<endl; return 0; } 7.1.2Image 1: This image shows another example of a simple program with some errors. The code has been written out below. #include <iostream> using namespace std; int main(void) { float a,b; while(cin >> a) { cin >> b; cout << a / b << endl; } return 0; } 7.1.3Image 1: This image shows another example of a simple program with errors. The code has been written out below. #include <iostream> using namespace std; int main(void) { float a,b; while(cin >> a) { cin >> b; if(b != 0.0) cout << a / b << endl; else cout << “Are you Kidding me?” << endl; } return 0; } 7.1.4Image 1: This image shows another example of a simple program with errors; this time, the div() function has also been included. The code has been written out below. #include <iostream> using namespace std; bool div (float &res, float arg1, float arg2) { if(arg2 == 0.0) return false; res = arg1 / arg2; return true; } int main(void) { float r, a, b; while(cin >> a) { cin >> b; if(div(r,a,b)) cout << r << endl; else cout << “Are you Kidding me?” << endl; } return 0; } 7.1.5Image 1: This image shows another example of a program with errors. The code is written out below. bool low_level_eval(….) { : if(something_went_wrong) return false; : } bool middle_level_eval(….) { : bool result = low_level_eval(….); if(!result) return false; : } bool top_level_eval(…) { : bool result = middle_level_eval(…); if(!result) return false; : } int main(void) { : bool result = top_level_eval(….); if(!result) { cout << “Sarcasm!” << endl; return 1; } } 7.1.6Image 1: This image shows a sculpture of Lucius Annaeus Seneca. 7.1.7Image 1: This image shows a diagram of the hierarchal structure of exceptions. The diagram is described below. The diagram shows an orange box, with the label "exception", which is linked to two separate blue boxes that are called: logic_error and runtime_error, respectively. 7.1.8Image 1: This image shows an example of a virtual function called what, which is used in the exception class. The code is written out below. virtual char* what() 7.1.9 Image 1: This image shows an example of the try function to detect exceptions in the program written out below. try { : : : } 7.1.10 Image 1: This image shows an example of the catch function, which is used to handle incoming exceptions in the program which has written out below. Catch(what) { : : : } 7.1.11Image 1: This image shows an example of the throw statement with an exception. The code is written out below. throw what; 7.1.12Image 1: This image shows a function that will perform division of floating numbers. if the results are not valid, the function will throw an exception with a complaint string. The code is written out below. float div(float a, float b) { if(b == 0.0) throw string(“I can’t believe – division by zero ”); return a / b; } 7.1.13Image 1: This image shows a complete program that will perform division of floating numbers. If the results are not valid the function will throw an exception with a complaint string. The code is written out below. #include<iostream> using namespace std; float div(float a, float b) { if(b == 0.0) throw string(“I can’t believe – division by zero ”); return a / b; } int main(void) { float a, b; while(cin >> a) { try { cin >> b; cout << div(a, b) << endl; } catch (string &problem) { cout << “Look what you did, you bad user!” << endl; cout << problem << endl; } } return 0; } 7.2.1Image 1: This image shows a function called DoCalculations, which contains the catch function and the throw statements. The code has been written out below. #include<iostream> using namespace std; float DoCalculations(float a, float b, float c, float d) { try { float x; if(a == 0.0) throw string(“Bad arg a”); x = 1 / a; if(b == 0.0) throw string(“Bad arg b”); x /= b; if(c == 0.0) throw string(“Bad arg c”); x /= c; if(d == 0.0) throw string(“Bad arg d”); return x / d; } catch(string &exc) { cout<<”Something bad happened: “<<exc<<endl; return 0; } } int main(void) { DoCalculations(1,2,3,0); return 0; } 7.2.2Image 1: This image shows the function called DoCalculations from the previous example. In this instance, The catch function has been moved into the main function. The code is written out below. #include<iostream> using namespace std; float DoCalculations(float a, float b, float c, float d) { try { float x; if(a == 0.0) throw string(“Bad arg a”); x = 1 / a; if(b == 0.0) throw string(“Bad arg b”); x /= b; if(c == 0.0) throw string(“Bad arg c”); x /= c; if(d == 0.0) throw string(“Bad arg d”); return x / d; } int main(void) { try { DoCalculations(1,2,3,0); }catch(string &exc) { cout << “Something bad happened: “ << exc << endl; } return 0; } 7.2.3Image 1: This image shows an example of function execution. The code is written out below. #include<iostream> using namespace std; class Class { public: Class(void) { cout << ”Object constructed” << endl; } ~Class(void) { cout << “Object destructed” << endl; } void Hello(void) {cout << “Object says: hello” << endl; } }; float DoCalculations(void) { Class object; Object.Hello(); return 0.0; } int main(void) { DoCalculations(); return 0; } 7.2.3Image: This image shows another example of function execution; the program has been modified to include throw statements. The code is written out below. #include<iostream> using namespace std; class Class { public: Class(void) { cout << ”Object constructed” << endl; } ~Class(void) { cout << “Object destructed” << endl; } void Hello(void) {cout << “Object says: hello” << endl; } }; void DoCalculations(int i) { if(i == 0) throw string(“fatal 1”); Class object; if(i == 1) throw string(“fatal 2”); object.Hello(); if(i == 2) throw string(“fatal 3”); } int main(void) { for(int i = 0; i < 3; i++) { try { cout << “______”<< endl; DoCalculations(i); } catch (string &exc) { cout << exc << endl; } } } return 0; } 7.2.5Image 1: This image shows an example of the throw statement, and the value that it throws in the Class program. The code is written out below. #include<iostream> using namespace std; class Class { public: string msg; Class(string txt) :msg(txt) {cout << “Object [“ << msg << “] constructed” << endl; } ~Class(void) { cout << “Object [“ << msg << “] destructed” << endl; } void Hello(void) { cout << “Object [“ << msg << “] says: hello” << endl; }; void DoCalculations(int i) { if(i == 0) throw Class(“exception 1”); Class object(“object”); if(i == 1) throw Class(“exception 2”); object.Hello(); if(i == 2) throw Class(“exception 3”); } int main(void) { for(int i = 0, i < 3; i++) { try { cout << “ _ _ _ _ _ _ _”<<endl; DoCalculations(i); }catch (Class &exc) { cout << “Caught!” << endl; cout << exc.msg << endl; } } return 0; } 7.2.6Image 1: This image shows a function in the class program, which is used to determine if there are any exceptions. The code is written out below. #include<iostream> using namespace std; class Class { public: string msg; Class(string txt) :msg(txt) {} }; void function(int i) { throw Class(“object”); } int main(void) { try { function(1); }catch(Class &exc) { cout << “Caught!” << endl; } return 0; } 7.2.7Image 1: This image shows a function in the class program, which includes throw specifications. The code is written out below. #include<iostream> using namespace std; class Class { public: string msg; Class(string txt) :msg(txt) {} }; void function(void) throw(Class) { throw Class(“object”); } int main(void) { try { function(); }catch(Class &exc) { cout << “Caught!” << endl; } return 0; } 7.2.8Image 1: This image shows a function of the class program which includes throw specifications of the wrong type. This causes errors in the program. The code is written out below. #include<iostream> using namespace std; class Class { public: string msg; Class(string txt) :msg(txt) {} }; void function(void) throw(Class) { throw string(“object”); } int main(void) { try { function(); }catch(Class &exc) { cout << “Caught!” << endl; } return 0; } 7.2.9Image 1: This image shows a function of the class program that includes throw specifications of the wrong type. This time, the errors in the throw specifications have been corrected, and the program functions as intended. The code is written out below. #include<iostream> using namespace std; class Class { public: string msg; Class(string txt) :msg(txt) {} }; void function(void) throw(Class) { throw string(“object”); } int main(void) { try { function(); }catch(string &exc) { cout << “Caught!” << endl; } return 0; } 7.2.10Image 1: This image shows a function of the class program, which includes throw specifications of the wrong type. These have been corrected again and the program functions as intended. The code is written out below. #include<iostream> using namespace std; class Class { public: string msg; Class(string txt) :msg(txt) {} }; void function(void) throw(string) { throw string(“object”); } int main(void) { try { function(); }catch(string &exc) { cout << “Caught!” << endl; } return 0; } 7.2.11Image 1: This image shows a function of the class program, which includes throw specifications of the wrong type. These mistakes may or may not be corrected in the code that is written out below. #include<iostream> using namespace std; class Class { public: string msg; Class(string txt) :msg(txt) {} }; void function(void) throw() { throw string(“object”); } int main(void) { try { function(); }catch(string &exc) { cout << “Caught!” << endl; } return 0; } 7.2.12Image 1: This image shows a function of the class program, which includes throw specifications of two different types. The code is written out below. #include<iostream> using namespace std; class Class { public: string msg; Class(string txt) :msg(txt) {} }; void function(int i) throw (string, Class) { switch(i) { case 0 : throw string(“string”); case 1 : throw Class(“object”); default : cout << “OK” << endl; } } void level(int i) throw(Class) { try { function(i); }catch(string &exc) { cout << “String [” << exc << “] caught in level()” << endl; } } int main(void) { for(int i = 0; i < 2; i++); cout << “_ _ _ _ _ _ _ _ _ _” << endl; try { level(i); } catch(Class &exc) { cout << “Object [“ << exc.msg << “] caught in main()” << endl; } } return 0; } 7.2.13Image 1: This image shows a variation of the class program that includes unexpected expectations. The code is written out below. #include<iostream> using namespace std; class Class { public: string msg; Class(string txt) :msg(txt) {} }; void function(void) throw () { throw string(“object”); } void lastchance(void) { cout << “See what you’ve done! You’ve thrown an illegal exception!” << endl; } int main(void) { set_unexpected(lastchance); try { function(); }catch(string &exc) { cout << “Caught!” << endl; } return 0; }; 7.3.1Image 1: This image shows the exception class hierarchy diagram which has been described below. The diagram shows an orange box with the label "exception", which is linked to two blue boxes that are called logic_error and runtime_error respectively. 7.3.2Image 1: This image shows an example of the explicit keyword in C++. The code is written out below. class A { public: explicit A(int) {} }; class B { public: B(int) {} }; int main(void) { A a = 1; //compilation error! B b = 1; return 0; } 7.3.3Image 1: This image shows an example of the exception class being used in C++. The code is written out below. #include <iostream> #include <exception> using namespace std; class A { public: virtual void f(void) {} }; class AA : public A { public: void aa(void) {}; }; int main(void) { A a; try { dynamic_cast<AA &>(a) .aa(); }catch (exception ex) { cout << “[“ << ex.what() << “]” << endl; } return 0; } 7.3.4Image 1: This image shows an example of the logic error class in C++. The code is written out below. class logic_error : public exception { public: explicit logic_error (const string& what_arg); } 7.3.5Image 1: This image shows an example of the domain error class in C++. The code is written out below. class domain_error : public logic_error { public: explicit domain_error (const string& what_arg); }; 7.3.6Image 1: This image shows an example of the invalid argument class in C++. The code is written out below. class invalid_argument: public logic_error { public: explicit invalid_argument (const string& what_arg); }; 7.3.7Image 1: This image shows an example of the length error class in C++. The code is written out below. class length_error: public logic_error { public: explicit length_error(const string& what_arg); }; 7.3.8Image 1: This image shows an example of the out of range class in C++. The code is written out below. class out_of_range: public logic_error { public: explicit out_of_range (const string& What_arg); 7.3.9Image 1: This image shows an example of the runtime error class in C++. The code is written out below. class runtime_error : public exception { public: explicit runtime_error (const string& what_arg); } 7.3.10Image 1: This image shows an example of the range error class in C++. The code is written out below. class range_error : public runtime_error { public: explicit range_error (const string& what_arg); }; 7.3.11Image 1: This image shows an example of the overflow error class in C++. The code is written out below. class overflow_error : public runtime_error { public: explicit overflow_error (const string& what_arg); }; 7.3.12Image 1: This image shows an example of the underflow error class in C++. The code is written out below. class underflow_error : public runtime_error { public : explicit underflow_error (const string& what_arg); }; 7.3.13Image 1: This image shows an example of an exception used to determine underflow errors in C++. The code is written out below. class underflow_speed_error : public underflow_error { }; 7.3.14Image 1: This image shows an example of the bad_alloc exception in C++. The code is written out below. exception <- bad_alloc 7.3.15Image 1: This image shows an example of a bad exception in C++. The code is written out below. #include <iostream> #include <exception> using namespace std; void function(void) throw(int) { throw 3.14; } int main(void) { try { function(); }catch(double f) { cout << “Got double” << endl; }catch(bad_exception bad) { cout << “It’s so bad…” << endl; } cout << “Done” << endl; return 0; } 7.3.16Image 1: This image shows another example of a bad exception. The code is written out below. #include <iostream> #include <exception> using namespace std; void unexp(void) { cout << “Unexpected exception arrived!” << endl; throw; } void function(void) throw(int, bad_excpetion) { throw 3.14; } int main(void) { set_unexpected(unexp); try{ function(); }catch(double f) { cout << “Got double” << endl; }catch(bad_exception bad) { cout << “It’s so bad…” << endl; } cout << “Done” << endl; return 0; } 7.4.1Image 1: This image shows a specialised form of the catch statement in C++. This has been written out below in the catch branch program example. #include <iostream> #include<exception> #include<stdexcept> using namespace std; void function(int i) { switch(i) { case 0 : throw out_of_range(“0”); case 1 : throw overflow_error(“1”); case 2 : throw domain_error(“2”); } } int main(void) { for(int i = 0; i < 3; i++) { try { function(i); } catch(….) { cout << “Exception caught!” << endl; } } return 0; } 7.4.2Image 1: This image shows another example of the specialised catch statement in the catch branch program, which has been altered. The code has been written out below. #include<iostream> #include<exception> #include<stdexcept> using namespace std; void function(int i) { switch(i) { case 0 : throw out_of_range(“0”); case 1 : throw overflow_error(“1”); case 2 : throw domain_error(“2”); case 3 : throw exception(); } } int main(void) { for(int i = 0; i < 4; i++) { try { function(i); } Catch(exception &ex) { cout << “Exception caught!” << ex.what() << endl; } } return 0; } 7.4.3Image 1: This image shows another example of a specialised catch statement used in the catch branch program. The program has now been altered to include four catch branches. The code is written out below. #include<iostream> #include<exception> #include<stdexcept> using namespace std; void function(int i) { switch(i) { case 0 : throw out_of_range(“0”); case 1 : throw overflow_error(“1”); case 2 : throw domain_error(“2”); case 3 : throw exception(); } } int main(void) { for(int i = 0; i < 4; i++) { try { function(i); } catch(out_of_range &ofr) { cout << “Out of range: “ << ofr.what() << endl; } catch(overflow_error &ofr) { cout << “Overflow: “ << ovf.what() << endl; } catch(domain_error &dmn) { cout << “Domain: “<< dmn.what() << endl; } catch(exception &ex) { cout<< “Exception: “ << ex.what() << endl; } } return 0; } 7.4.4Image 1: This image shows another example of a specialised catch statement in the catch branch program. The program has been altered to include a generic error branch in addition to the other branches. The code is written out below. #include<iostream> #include<exception> #include<stdexcept> using namespace std; void function(int i) { switch(i) { case 0 : throw out_of_range(“0”); case 1 : throw overflow_error(“1”); case 2 : throw domain_error(“2”); case 3 : throw exception(); case 4 : throw “so bad”; } } int main(void) { for(int i = 0; i < 5; i++) { try { function(i); } catch(out_of_range &ofr) { cout << “Out of range: “ << ofr.what() << endl; } catch(overflow_error &ofr) { cout << “Overflow: “ << ovf.what() << endl; } catch(domain_error &dmn) { cout << “Domain: “<< dmn.what() << endl; } catch(exception &ex) { cout<< “Exception: “ << ex.what() << endl; } catch(….) { cout << “something bad happened” << endl; } } return 0; } 7.4.5Image 1: This image shows another example of the specialised catch statement in the catch branch program. The program has been altered again, with the catch branches in a rearranged order. The code is written out below. #include<iostream> #include<exception> #include<stdexcept> using namespace std; void function(int i) { switch(i) { case 0 : throw out_of_range(“0”); case 1 : throw overflow_error(“1”); case 2 : throw domain_error(“2”); case 3 : throw exception(); case 4 : throw “so bad”; } } int main(void) { for(int i = 0; i < 5; i++) { try { function(i); } catch(overflow_error &ofr) { cout << “Overflow: “ << ovf.what() << endl; } catch(out_of_range &ofr) { cout << “Out of range: “ << ofr.what() << endl; } catch(domain_error &dmn) { cout << “Domain: “<< dmn.what() << endl; } catch(exception &ex) { cout<< “Exception: “ << ex.what() << endl; } catch(….) { cout << “something bad happened” << endl; } } return 0; } 7.4.6Image 1: This image shows another example of the specialised catch statement in the catch branch program. The code has been altered, with the order of the catch branches having been rearranged again. The code is written out below. #include<iostream> #include<exception> #include<stdexcept> using namespace std; void function(int i) { switch(i) { case 0 : throw out_of_range(“0”); case 1 : throw overflow_error(“1”); case 2 : throw domain_error(“2”); case 3 : throw exception(); case 4 : throw “so bad”; } } int main(void) { for(int i = 0; i < 5; i++) { try { function(i); } catch(exception &ex) { cout<< “Exception: “ << ex.what() << endl; } catch(out_of_range &ofr) { cout << “Out of range: “ << ofr.what() << endl; } catch(overflow_error &ofr) { cout << “Overflow: “ << ovf.what() << endl; } catch(domain_error &dmn) { cout << “Domain: “<< dmn.what() << endl; } catch(….) { cout << “something bad happened” << endl; } } return 0; } 7.4.7Image 1: This image shows the importance of order in rearranged catch statements for the catch branch program. The code is written out below.
using namespace std; void function(int i) { switch(i) { case 0 : throw domain_error(“0”); case 1 : throw logic_error(“1”); case 2 : throw exception(); case 3 : throw range_error(“2”); case 4 : throw “so bad”; } } int main(void) { for(int i = 0; i < 5; i++) { try { function(i); } catch(exception &ex) { cout<< “Exception: “ << ex.what() << endl; } } return 0; } 7.4.8Image 1: This image shows another example of rearranged catch branch statements with an ellipsis branch statement for the catch branch program. The code has been written out below. #include<iostream> #include<exception> #include<stdexcept> using namespace std; void function(int i) { switch(i) { case 0 : throw domain_error(“0”); case 1 : throw logic_error(“1”); case 2 : throw exception(); case 3 : throw range_error(“2”); case 4 : throw “so bad”; } } int main(void) { for(int i = 0; i < 5; i++) { try { function(i); } catch(exception &ex) { cout<< “Exception: “ << ex.what() << endl; } catch(….) { cout << “Something bad happened” << endl; } } return 0; } 7.4.9Image 1: This image shows another example of rearranged catch branch statements with an ellipsis branch statement for the catch branch program. The code has been written out below. #include<iostream> #include<exception> #include<stdexcept> using namespace std; void function(int i) { switch(i) { case 0 : throw domain_error(“0”); case 1 : throw logic_error(“1”); case 2 : throw exception(); case 3 : throw range_error(“2”); case 4 : throw “so bad”; } } int main(void) { for(int i = 0; i < 5; i++) { try { function(i); } catch(logic_error &le) { cout << “Logic error: “ << le.what() << endl; } catch(exception &ex) { cout<< “Exception: “ << ex.what() << endl; } catch(….) { cout << “Something bad happened” << endl; } } return 0; } 7.4.10Image 1: This image shows another example of rearranged catch branch statements with an ellipsis branch statement for the catch branch program. The code is written out below. #include<iostream> #include<exception> #include<stdexcept> using namespace std; void function(int i) { switch(i) { case 0 : throw domain_error(“0”); case 1 : throw logic_error(“1”); case 2 : throw exception(); case 3 : throw range_error(“2”); case 4 : throw “so bad”; } } int main(void) { for(int i = 0; i < 5; i++) { try { function(i); } catch(logic_error &le) { cout << “Logic error: “ << le.what() << endl; } catch(runtime_error &re) { cout << “Runtime error” << re.what() << endl; } catch(exception &ex) { cout<< “Exception: “ << ex.what() << endl; } catch(….) { cout << “Something bad happened” << endl; } } return 0; } 7.4.11Image 1: This image shows the catch branch program, with a broker function to handle some of the exceptions in the program. The code has been written out below. #include<iostream> #include<exception> #include<stdexcept> using namespace std; void function(int i) { switch(i) { case 0 : throw domain_error(“0”); case 1 : throw logic_error(“1”); case 2 : throw exception(); case 3 : throw range_error(“2”); case 4 : throw “so bad”; } } void broker(int i) { try { function(i); } catch(exception ex) {cout << “Broker – exception: “ << ex.what() << endl; } int main(void) { for(int i = 0; i < 5; i++) { try { broker(i); } catch(logic_error &le) { cout << “Logic error: “ << le.what() << endl; } catch(runtime_error &re) { cout << “Runtime error” << re.what() << endl; } catch(exception &ex) { cout<< “Exception: “ << ex.what() << endl; } catch(….) { cout << “Something bad happened” << endl; } } return 0; } 7.4.12Image 1: This image shows another example of the catch branch program, with a broker function to handle some of the exceptions in the catch branch program. The code is written out below. #include<iostream> #include<exception> #include<stdexcept> using namespace std; void function(int i) { switch(i) { case 0 : throw domain_error(“0”); case 1 : throw logic_error(“1”); case 2 : throw exception(); case 3 : throw range_error(“2”); case 4 : throw “so bad”; } } void broker(int i) { try { function(i); } catch(logic_error &le) {cout << “Broker – logic_error: “ << le.what() << endl; } int main(void) { for(int i = 0; i < 5; i++) { try { broker(i); } catch(logic_error &le) { cout << “Logic error: “ << le.what() << endl; } catch(runtime_error &re) { cout << “Runtime error” << re.what() << endl; } catch(exception &ex) { cout<< “Exception: “ << ex.what() << endl; } catch(….) { cout << “Something bad happened” << endl; } } return 0; } 7.4.13Image 1: This image shows another example of the catch branch program, with a broker to handle some of the exceptions in the catch branch program. The code is written out below. #include<iostream> #include<exception> #include<stdexcept> using namespace std; void function(int i) { switch(i) { case 0 : throw domain_error(“0”); case 1 : throw logic_error(“1”); case 2 : throw exception(); case 3 : throw range_error(“2”); case 4 : throw “so bad”; } } void broker(int i) { try { function(i); } catch(….) { cout << “Broker swept problems under the carpet “ << endl; } } int main(void) { for(int i = 0; i < 5; i++) { try { broker(i); } catch(logic_error &le) { cout << “Logic error: “ << le.what() << endl; } catch(runtime_error &re) { cout << “Runtime error” << re.what() << endl; } catch(exception &ex) { cout<< “Exception: “ << ex.what() << endl; } catch(….) { cout << “Something bad happened” << endl; } } return 0; } 7.4.14Image 1: This image shows another example of the catch branch program, with a broker to handle some of the exceptions in the catch branch program. The code is written out below. #include<iostream> #include<exception> #include<stdexcept> using namespace std; void function(int i) { switch(i) { case 0 : throw domain_error(“0”); case 1 : throw logic_error(“1”); case 2 : throw exception(); case 3 : throw range_error(“2”); case 4 : throw “so bad”; } } void broker(int i) { try { function(i); } catch(….) { cout << “Broker swept problems under the carpet “ << endl; throw; } } int main(void) { for(int i = 0; i < 5; i++) { try { broker(i); } catch(logic_error &le) { cout << “Logic error: “ << le.what() << endl; } catch(runtime_error &re) { cout << “Runtime error” << re.what() << endl; } catch(exception &ex) { cout<< “Exception: “ << ex.what() << endl; } catch(….) { cout << “Something bad happened” << endl; } } return 0; } 7.5.1Image 1: This image shows a stack and an array in combined form in a C++ program. The code is written out below. class Stack { private: int *stackstore; int stacksize; int SP; public: Stack(int size = 100); ~Stack(); void push(int value); int pop(void); }; Stack::Stack(int size) { stackstore = new int[size]; stacksize = size; SP = 0; } Stack::~Stack(void) { delete []stackstore; } void Stack::push(int value) { stackstore[sp++] = value; } int Stack::pop(void) { return stackstore[--SP]; } #include<iostream> using namespace std; int main(void) { Stack stk; stk.push(1); cout << stk.pop() << endl; return 0; } 7.5.2Image 1: This image shows a list of stack exceptions. The list is written out below. 1: stack_size_error 2: stack_bad_alloc 3: stack_overflow 4: stack_empty 7.5.3Image 1: This image shows a stack program with declarations of the projected classes. The code is written out below. #include<iostream> #include<exception> #include<stdexcept> class stack_size_error : public std::length_error { public: explicit stack_size_error(const std::string &msg); }; class stack_bad_alloc : public std::bad_alloc { public: explicit stack_bad_alloc(void); }; class stack_overflow : public std::logic_error { public: explicit stack_overflow(const std::string &msg); }; class stack_empty : public std::logic_error { public: explicit stack_empty(const std::string &msg); }; 7.5.4Image 1: This image shows the definitions for the previous declarations in 7.5.3. The code is written out below. stack_size_error::stack_size_error(const std::string &msg) : std::length_error(msg) { }; stack_bad_alloc::stack_bad_alloc(void) : std::bad_alloc() { }; stack_overflow::stack_overflow(const std::string &msg) : std::logic_error(msg) { }; stack_empty::stack_empty(const std::string &msg) : std::logic_error(msg) { }; 7.5.5Image 1: This image shows a stack program with a new set of stack declarations. The code is written out below. class Stack{ private: int *stackstore; int stacksize; int SP; public: Stack(int size = 100) throw(stack_size_error, stack_bad_alloc); ~Stack(); void push(int value) throw(stack_overflow); int pop(void) throw(stack_empty); }; 7.5.6Image 1: This image shows a stack program with an improved constructor. The code is written out below. Stack::Stack(int size) throw(stack_size_error, stack_bad_alloc) { if(size <= 0) throw stack_size_error(“size must be >= 0”); try { stackstore = new int[size]; } catch(std::bad_alloc ba) { throw stack_bad_alloc(); } stacksize = size; SP = 0; }; 7.5.7Image 1: This image shows a stack program with a modified push function. The code is written out below. void Stack::push (int value) throw(stack_overflow) { if(SP == stacksize) throw stack_overflow(“stack size exceeded”); stackstore[SP++] = value; } 7.5.8Image 1: This image shows a stack program with a new pop function added. The code is written out below. int Stack::pop throw(stack_empty) { if(SP == 0) throw stack_empty(“stack is empty”); return stackstore[--SP]; } 7.5.9Image 1: This image shows a stack program that acts as an aggregate for two source files. The code is written out below. #ifndef_MYSTACK_ #define_MYSTACK_ #include<iostream> #include<exception> #include<stdexcept> class stack_size_error : public std::length_error { public: explicit stack_size_error(const std::string &msg); }; class stack_bad_alloc : public std::bad_alloc { public: explicit stack_bad_alloc(void); }; class stack_overflow : public std::logic_error { public: explicit stack_overflow(const std::string &msg); }; class stack_empty : public std::logic_error { public: explicit stack_empty(const std::string &msg); }; class Stack { private: int * stackstore; int stacksize; int SP; public: Stack(int size = 100) throw(stack_size_error, stack_bad_alloc); ~Stack(); void push(int value) throw(stack_overflow); int pop(void) throw(stack_empty); }; #endif 7.5.10Image 1: This image shows the contents of the program "mystack.cpp" with a header file included. The code is written out below. #include “mystack.h” stack_size_error::stack_size_error(const std::string &msg) : std::length_error(msg) { }; stack_bad_alloc::stack_bad_alloc(void) : std::bad_alloc() { }; stack_overflow::stack_overflow(const std::string &msg) : std::logic_error(msg) { }; stack_empty::stack_empty(const std::string &msg) : std::logic_error(msg) { }; Stack::Stack (int size) throw(stack_size_error, stack_bad_alloc) { if(size <= 0); throw stack_size_error(“size nust be >= 0”); try { stackstore = new int[size]; }catch(std::bad_alloc ba) { throw stack_bad_alloc(); } stacksize = size; SP = 0; } Stack::~Stack(void) { delete stackstore; } void Stack::push(int value) throw(stack_overflow) { if(SP == stacksize) throw stack_overflow(“stack size exceeded”); stackstore[SP++] = value; }; int Stack::pop(void) throw(stack_empty) { if(SP == 0) throw stack_empty(“stack is empty”); return stackstore[--SP]; } 7.5.11Image 1: This image shows a stack program with a main function included to run the program. The code has been written out below. #include “mystack.h” #include <iostream> using namespace std; int main(void) { Stack stk; stk.push(1); cout << stk.pop() << endl; return 0; } 7.5.12Image 1: This image shows a stack program nicknamed crash test, which is used to test the main program for errors. The code is written out below. #include “mystack.h” #include<iostream> using namespace std; int main(void) { try { Stack stk; stk.push(1); cout << stk.pop() << endl; } catch(stack_bad_alloc sba) { cout << “No room for the stack – sorry!” << endl; } catch(stack_size_error sse) { cout << “Stacks of that size don’t exist – sorry!” << endl; } catch(stack_overflow se) { cout << “Stack is too small for that many pushes – sorry!” << endl; } catch(stack_empty su) { cout << “Stack is empty – sorry!” << endl; } return 0; } 7.5.13Image 1: This image shows another example of the crash test program, which is used to see if the constructor in the crash test program is working properly. The code is written out below. #include “mystack.h” #include<iostream> using namespace std; int main(void) { try { Stack stk(0); stk.push(1); cout << stk.pop() << endl; } catch(stack_bad_alloc sba) { cout << “No room for the stack – sorry!” << endl; } catch(stack_size_error sse) { cout << “Stacks of that size don’t exist – sorry!” << endl; } catch(stack_overflow se) { cout << “Stack is too small for that many pushes – sorry!” << endl; } catch(stack_empty su) { cout << “Stack is empty – sorry!” << endl; } return 0; } 7.5.14Image 1: This image shows another example of the crash test program, used to see if the constructor can handle exorbitant demands of the stack size. The code is written out below. #include “mystack.h” #include<iostream> using namespace std; int main(void) { try { Stack stk(2000000000); stk.push(1); cout << stk.pop() << endl; } catch(stack_bad_alloc sba) { cout << “No room for the stack – sorry!” << endl; } catch(stack_size_error sse) { cout << “Stacks of that size don’t exist – sorry!” << endl; } catch(stack_overflow se) { cout << “Stack is too small for that many pushes – sorry!” << endl; } catch(stack_empty su) { cout << “Stack is empty – sorry!” << endl; } return 0; } 7.5.15Image 1: This image shows another example of the crash test program, used to see if the crash test program is push proof. The code is written out below. #include “mystack.h” #include<iostream> using namespace std; int main(void) { try { Stack stk(1); stk.push(1); stk.push(2); cout << stk.pop() << endl; } catch(stack_bad_alloc sba) { cout << “No room for the stack – sorry!” << endl; } catch(stack_size_error sse) { cout << “Stacks of that size don’t exist – sorry!” << endl; } catch(stack_overflow se) { cout << “Stack is too small for that many pushes – sorry!” << endl; } catch(stack_empty su) { cout << “Stack is empty – sorry!” << endl; } return 0; } 7.5.16Image 1: This image shows another example of the crash test program, used to see if the crash test program has too many pops. The code is written out below. #include “mystack.h” #include<iostream> using namespace std; int main(void) { try { Stack stk(1); stk.push(1); cout << stk.pop() << endl; cout << stk.pop() << endl; } catch(stack_bad_alloc sba) { cout << “No room for the stack – sorry!” << endl; } catch(stack_size_error sse) { cout << “Stacks of that size don’t exist – sorry!” << endl; } catch(stack_overflow se) { cout << “Stack is too small for that many pushes – sorry!” << endl; } catch(stack_empty su) { cout << “Stack is empty – sorry!” << endl; } return 0; } |