关于异常的使用,最简单的示例:
int main() { try { throw(string("gaoyuelong")); } catch (string str) { cout << str << endl; } return 0; }
需要注意的是异常必须被处理,否则程序就会奔溃,比如:
int main() { throw("123"); //throw异常必须被处理 return 0; }
抛出异常后,throw后面的语句不会被执行
int main() { int age = 100; try { if (age > 90) { throw(age); //throw后面的语句不会被执行到 cout << "123" << endl; } } catch (int age) { cout << age << " is too big" << endl; } return 0; }
异常会向外传播,直到找到第一个匹配的catch处理(catch实际上是匹配过程,catch按顺序执行,他会执行第一个能匹配到的捕获)
void inner() { //在外层被捕获 throw("123"); } void outer() { try { inner(); } catch (...) { cout << "exception caught" << endl; } } int main() { outer(); return 0; }
void inner() { //在内层捕获 try { throw("123"); } catch (...) { cout << "caught in inner func" << endl; } } void outer() { try { inner(); } catch (...) { cout << "exception caught" << endl; } }
当我们想自定义异常输出信息时,需要继承自exception类
class idontknowwhatshappening : public exception { public: idontknowwhatshappening() = default; ~idontknowwhatshappening() = default; idontknowwhatshappening& operator=(const idontknowwhatshappening&) = default; //返回const char*而不是string,string可能也会发生异常 const char* what() { return "I don't know what's happening"; }; }; void inner() { try { throw(idontknowwhatshappening()); } catch (idontknowwhatshappening &e) { cout << e.what() << endl; } } void outer() { try { inner(); } catch (...) { cout << "exception caught" << endl; } }
若当前匹配的catch处理不了,可以修改/携带信息,可以继续向上抛出
class i : public exception { public: i() = default; ~i() = default; i& operator=(const i&) = default; const char* what() { return "exception i"; } string s; }; void outer() { try { throw i(); } catch (i& I) { I.s = "123"; cout << "exception caught" << endl; cout << I.s << endl; //继续向上层抛出 throw; } } int main() { try { outer(); } catch (i &I) { cout << "main: " << I.s << endl; } return 0; }
用noexcept修饰后,不能再抛出异常了,否则程序会崩溃
const char* foo() noexcept { throw("123"); } int main() { try { foo(); } catch (...) { cout << "exception caught" << endl; } return 0; }
一种使用规范,异常通常由调用者捕获处理
void Process(int n) { if (n > 3) { //去外面处理,不要在使用方处理 throw runtime_error("number too big"); } } int main() { vector<int> v = { 1, 2, 3, 4, 5 }; for (int i = 0; i < 5; i++) { try { Process(v[i]); cout << v[i] << endl; } catch (runtime_error &e) { cout << e.what() << endl; } } return 0; }