捕捉异常
try/catch
块用于捕获异常。try
部分中的代码是可能抛出异常的代码,catch
子句中的代码处理异常。
#include <iostream>
#include <string>
#include <stdexcept>
int main() {
std::string str("foo");
try {
str.at(10); // access element, may throw std::out_of_range
} catch (const std::out_of_range& e) {
// what() is inherited from std::exception and contains an explanatory message
std::cout << e.what();
}
}
多个 catch
子句可用于处理多种异常类型。如果存在多个 catch
子句,则异常处理机制会尝试按照它们在代码中的出现顺序进行匹配 :
std::string str("foo");
try {
str.reserve(2); // reserve extra capacity, may throw std::length_error
str.at(10); // access element, may throw std::out_of_range
} catch (const std::length_error& e) {
std::cout << e.what();
} catch (const std::out_of_range& e) {
std::cout << e.what();
}
可以使用公共基类的单个 catch
子句捕获从公共基类派生的异常类。上面的例子可以用 std:exception
的单个子句替换 std::length_error
和 std::out_of_range
的两个 catch
子句:
std::string str("foo");
try {
str.reserve(2); // reserve extra capacity, may throw std::length_error
str.at(10); // access element, may throw std::out_of_range
} catch (const std::exception& e) {
std::cout << e.what();
}
因为 catch
子句是按顺序尝试的,所以一定要先编写更具体的 catch 子句,否则你的异常处理代码可能永远不会被调用:
try {
/* Code throwing exceptions omitted. */
} catch (const std::exception& e) {
/* Handle all exceptions of type std::exception. */
} catch (const std::runtime_error& e) {
/* This block of code will never execute, because std::runtime_error inherits
from std::exception, and all exceptions of type std::exception were already
caught by the previous catch clause. */
}
另一种可能性是 catch-all 处理程序,它将捕获任何抛出的对象:
try {
throw 10;
} catch (...) {
std::cout << "caught an exception";
}