捕捉異常
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";
}