1. 概念
异常说明/规范(exception specification)指定, 如果函数抛出异常, 被抛出的异常将是包含在该说明中的一种, 或者是从列出的异常中派生的类型.
2. 定义
异常说明跟在函数形参表之后. 一个异常说明在关键字throw之后跟着一个(可能为空的)由圆括号括起来的异常类型列表. 如:
void foo(int) throw (std::logic_error, std::runtime_error);
这个声明指出, foo是接受int值的函数, 返回void. 如果foo抛出一个异常, 该异常将是std::logic_error或std::runtime_error对象, 或者由std::logic_error或std::runtime_error派生的类型的异常.
3. 说明
4. 代码
// usr_excep.h -- exception classes for hmean(), gmean() #include <iostream> class bad_hmean { private: double v1; double v2; public: bad_hmean(double a = 0, double b = 0) : v1(a), v2(b){} void mesg(); }; inline void bad_hmean::mesg() { std::cout << "hmean(" << v1 << ", " << v2 <<"): " << "invalid arguments: a = -b/n"; } class bad_gmean { public: double v1; double v2; bad_gmean(double a = 0, double b = 0) : v1(a), v2(b){} const char * mesg(); }; inline const char * bad_gmean::mesg() { return "gmean() arguments should be >= 0/n"; }
//foo.cpp -- unwinding the stack #include <iostream> #include <cmath> // or math.h, unix users may need -lm flag #include <cstring> #include "usr_excep.h" class demo { private: char word[40]; public: demo (const char * str) { std::strcpy(word, str); std::cout << "demo " << word << " created/n"; } ~demo() { std::cout << "demo " << word << " destroyed/n"; } void show() const { std::cout << "demo " << word << " lives!/n"; } }; // function prototypes double hmean(double a, double b) throw(bad_hmean); double gmean(double a, double b) throw(bad_gmean); double means(double a, double b) throw(bad_hmean, bad_gmean); int main() { using std::cout; using std::cin; using std::endl; double x, y, z; demo d1("found in main()"); cout << "Enter two numbers: "; while (cin >> x >> y) { try { // start of try block z = means(x,y); cout << "The mean mean of " << x << " and " << y << " is " << z << endl; cout << "Enter next pair: "; } // end of try block catch (bad_hmean & bg) // start of catch block { bg.mesg(); cout << "Try again./n"; continue; } catch (bad_gmean & hg) { cout << hg.mesg(); cout << "Values used: " << hg.v1 << ", " << hg.v2 << endl; cout << "Sorry, you don't get to play any more./n"; break; } // end of catch block } d1.show(); cout << "Bye!/n"; return 0; } double hmean(double a, double b) throw(bad_hmean) { if (a == -b) { throw bad_hmean(a,b); } return 2.0 * a * b / (a + b); } double gmean(double a, double b) throw(bad_gmean) { if (a < 0 || b < 0) { throw bad_gmean(a, b); } return std::sqrt(a * b); } double means(double a, double b) throw(bad_hmean, bad_gmean) { double am, hm, gm; demo d2("found in means()"); am = (a + b) / 2.0; // arithmetic mean try { hm = hmean(a, b); gm = gmean(a, b); } catch (bad_hmean & bg) // start of catch block { bg.mesg(); std::cout << "Caught in means()/n"; throw; // rethrows the exception } d2.show(); return (am + hm + gm) / 3.0; }