#include #include #include #include // for sqrt() #include #include #include // for istreamstream/ostringstream #include // for SHRT_MAX #include // for typeid operator using namespace std; ostream& operator<<(ostream& out, const exception& error) { out << "I caught an error of type: " << typeid(error).name() << "\nMessage: " << error.what() << endl; return out; } class my_domain_error : public domain_error { public: my_domain_error(const char* message) : domain_error(message) {} // override the virtual what() function const char* what() const noexcept override { static char temp[128]; strcpy(temp,"my_domain_error: "); strcat(temp,domain_error::what()); return temp; } }; double mysqrt1(double number) throw (domain_error) { if (number < 0) throw domain_error("mysqrt1 error: negative argument"); return sqrt(number); } double mysqrt2(double number) throw (my_domain_error) { if (number < 0) throw my_domain_error("mysqrt2 error: negative argument"); return sqrt(number); } // Derive the zero_denominator class from invalid_argument class zero_denominator : public invalid_argument { public: zero_denominator() : invalid_argument("Error: zero denominator") { } }; class fraction { int numerator, denominator; public: fraction(int n = 0, int d = 1) : numerator(n), denominator(d) { if (d == 0 ) throw zero_denominator(); } }; // convert a hexadecimal string to unsigned int unsigned hex_string_to_unsigned(const string& text) throw (invalid_argument) { if (text.find_first_not_of("0123456789abcdefABCDEF") != string::npos) { throw invalid_argument(string("Invalid hexadecimal char in: " ) + text); } istringstream sin(text); unsigned number; sin >> hex >> number; return number; } // returns sum of two shorts, make sure sum is valid short short add2shorts(short one, short two, bool check_limit = false) throw (overflow_error) { if (check_limit) { if (static_cast(one) + two > SHRT_MAX) // SHRT_MAX = 32767 { ostringstream sout; sout << "add2shorts failed with arguments " << one << " and " << two; throw overflow_error(sout.str()); } } return one + two; } int main() { // test throw/catch of domain_error try { cout << "mysqrt1(2.0)=" << mysqrt1(2.0) << endl; cout << "mysqrt1(-2.0)=" << mysqrt1(-2.0) << endl; } catch (const domain_error& error) { cerr << "Line " << __LINE__ << ": " << error << endl; } // test throw/catch of logic_error try { cout << "mysqrt1(-2.0)=" << mysqrt1(-2.0) << endl; } catch (const logic_error& error) { cerr << "Line " << __LINE__ << ": " << error << endl; } // test throw/catch of (base class) exception try { cout << "mysqrt1(-2.0)=" << mysqrt1(-2.0) << endl; } catch (const exception& error) { cerr << "Line " << __LINE__ << ": " << error << endl; } // test throw/catch of my_domain_error try { cout << "mysqrt2(-2.0)=" << mysqrt2(-2.0) << endl; } catch (const my_domain_error& error) { cerr << "Line " << __LINE__ << ": " << error << endl; } // test throw/catch of zero_denominator try { fraction F(2,0); } catch (const zero_denominator& error) { cerr << "Line " << __LINE__ << ": " << error << endl; } // test throw/catch of invalid_argument try { cout << "hex abc=" << hex_string_to_unsigned(string("abc")) << endl; cout << "hex abz=" << hex_string_to_unsigned(string("abz")) << endl; } catch (const invalid_argument& error) { cerr << "Line " << __LINE__ << ": " << error << endl; } // test throw/catch of overflow_error try { cout << "short 31000+32000=" << add2shorts(31000,32000) << endl; cout << "short 31000+32000=" << add2shorts(31000,32000,true) << endl; } catch (const overflow_error& error) { cerr << "Line " << __LINE__ << ": " << error << endl; } }