throw 表达式;
该语句拋出一个异常。异常是一个表达式,其值的类型可以是基本类型,也可以是类。
try {
语句组
}
catch(异常类型) {
异常处理代码
}
...
catch(异常类型) {
异常处理代码
}
{}
中的内容称作“try块”,把 catch 和其后{}
中的内容称作“catch块”。#include <iostream> using namespace std; int main() { double m ,n; cin >> m >> n; try { cout << "before dividing." << endl; if( n == 0) throw -1; //抛出int类型异常 else cout << m / n << endl; cout << "after dividing." << endl; } catch(double d) { cout << "catch(double) " << d << endl; } catch(int e) { cout << "catch(int) " << e << endl; } cout << "finished" << endl; return 0; }程序的运行结果如下:
catch(int e)
块执行,该 catch 块执行完毕后,程序继续往后执行,直到正常结束。catch(int e)
,改为catch(char e)
,当输入的 n 为 0 时,拋出的整型异常就没有 catch 块能捕获,这个异常也就得不到处理,那么程序就会立即中止,try...catch 后面的内容都不会被执行。
catch(...) {
...
}
#include <iostream> using namespace std; int main() { double m, n; cin >> m >> n; try { cout << "before dividing." << endl; if (n == 0) throw - 1; //抛出整型异常 else if (m == 0) throw - 1.0; //拋出 double 型异常 else cout << m / n << endl; cout << "after dividing." << endl; } catch (double d) { cout << "catch (double)" << d << endl; } catch (...) { cout << "catch (...)" << endl; } cout << "finished" << endl; return 0; }程序的运行结果如下:
catchy(...)
捕获。catch (double)
和catch(...)
都能匹配该异常,但是catch(double)
是第一个能匹配的 catch 块,因此会执行它,而不会执行catch(...)
块。catch(...)
能匹配任何类型的异常,它后面的 catch 块实际上就不起作用,因此不要将它写在其他 catch 块前面。
#include <iostream> #include <string> using namespace std; class CException { public: string msg; CException(string s) : msg(s) {} }; double Devide(double x, double y) { if (y == 0) throw CException("devided by zero"); cout << "in Devide" << endl; return x / y; } int CountTax(int salary) { try { if (salary < 0) throw - 1; cout << "counting tax" << endl; } catch (int) { cout << "salary < 0" << endl; } cout << "tax counted" << endl; return salary * 0.15; } int main() { double f = 1.2; try { CountTax(-1); f = Devide(3, 0); cout << "end of try block" << endl; } catch (CException e) { cout << e.msg << endl; } cout << "f = " << f << endl; cout << "finished" << endl; return 0; }程序的输出结果如下:
f = Devide(3, 0);
。#include <iostream> #include <string> using namespace std; int CountTax(int salary) { try { if( salary < 0 ) throw string("zero salary"); cout << "counting tax" << endl; } catch (string s ) { cout << "CountTax error : " << s << endl; throw; //继续抛出捕获的异常 } cout << "tax counted" << endl; return salary * 0.15; } int main() { double f = 1.2; try { CountTax(-1); cout << "end of try block" << endl; } catch(string s) { cout << s << endl; } cout << "finished" << endl; return 0; }程序的输出结果如下:
throw;
没有指明拋出什么样的异常,因此拋出的就是 catch 块捕获到的异常,即 string("zero salary")。这个异常会被 main 函数中的 catch 块捕获。
void func() throw (int, double, A, B, C);
或void func() throw (int, double, A, B, C){...}
上面的写法表明 func 可能拋出 int 型、double 型以及 A、B、C 三种类型的异常。异常声明列表可以在函数声明时写,也可以在函数定义时写。如果两处都写,则两处应一致。void func() throw ();
则说明 func 函数不会拋出任何异常。#include <iostream> #include <stdexcept> using namespace std; class Base { virtual void func() {} }; class Derived : public Base { public: void Print() {} }; void PrintObj(Base & b) { try { Derived & rd = dynamic_cast <Derived &>(b); //此转换若不安全,会拋出 bad_cast 异常 rd.Print(); } catch (bad_cast & e) { cerr << e.what() << endl; } } int main() { Base b; PrintObj(b); return 0; }程序的输出结果如下:
#include <iostream> #include <stdexcept> using namespace std; int main() { try { char * p = new char[0x7fffffff]; //无法分配这么多空间,会抛出异常 } catch (bad_alloc & e) { cerr << e.what() << endl; } return 0; }程序的输出结果如下:
#include <iostream> #include <stdexcept> #include <vector> #include <string> using namespace std; int main() { vector<int> v(10); try { v.at(100) = 100; //拋出 out_of_range 异常 } catch (out_of_range & e) { cerr << e.what() << endl; } string s = "hello"; try { char c = s.at(100); //拋出 out_of_range 异常 } catch (out_of_range & e) { cerr << e.what() << endl; } return 0; }程序的输出结果如下:
v.at(100)
换成v[100]
,将s.at(100)
换成s[100]
,程序就不会引发异常(但可能导致程序崩溃)。因为 at 成员函数会检测下标越界并拋出异常,而 operator[] 则不会。operator [] 相比 at 的好处就是不用判断下标是否越界,因此执行速度更快。Copyright © 广州京杭网络科技有限公司 2005-2025 版权所有 粤ICP备16019765号
广州京杭网络科技有限公司 版权所有