捕捉異常

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_errorstd::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";
}