C/C++中函數(shù)分裝時錯誤處理的常見方法
1. 使用返回值(錯誤碼)
適用于簡單函數(shù),尤其是性能敏感的場景。
// 返回 0 表示成功,非 0 表示錯誤碼
int ComputeSomething(int input, double& output) {
if (input < 0) {
return 1; // 錯誤碼 1:非法輸入
}
output = sqrt(input);
return 0; // 成功
}
// 調(diào)用示例:
double result;
int err = ComputeSomething(-1, result);
if (err != 0) {
std::cerr << "Error: " << err << std::endl;
// 處理錯誤...
}
優(yōu)點:
- 簡單直接,性能高(無異常開銷)。
- 適用于嵌入式或高性能計算。
缺點:
- 調(diào)用者必須檢查返回值,容易遺漏。
- 錯誤信息不夠豐富(只能返回數(shù)字代碼)。
2. 使用 std::optional 或 std::expected(C++23)
適用于可能失敗但不需要詳細錯誤信息的函數(shù)。
#include <optional>
#include <cmath>
std::optional<double> SafeSqrt(double x) {
if (x < 0) {
return std::nullopt; // 表示失敗
}
return sqrt(x);
}
// 調(diào)用示例:
auto result = SafeSqrt(-1);
if (!result) {
std::cerr << "Error: Invalid input" << std::endl;
// 處理錯誤...
}
優(yōu)點:
- 比錯誤碼更清晰,避免魔數(shù)(magic numbers)。
- 適用于可能失敗但不需要詳細錯誤信息的場景。
缺點:
無法攜帶詳細的錯誤信息(只能表示成功/失?。?/p>
3. 拋出異常(throw)
適用于嚴重錯誤或不可恢復的錯誤。
#include <stdexcept>
double ComputeSomething(int input) {
if (input < 0) {
throw std::invalid_argument("Input must be non-negative");
}
return sqrt(input);
}
// 調(diào)用示例:
try {
double result = ComputeSomething(-1);
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
// 處理錯誤...
}
優(yōu)點:
- 錯誤信息豐富(可以攜帶字符串描述)。
- 適用于嚴重錯誤,避免錯誤傳播。
缺點:
- 異常處理有額外開銷。
- 濫用異??赡軐е麓a難以維護。
4. 使用自定義錯誤結構(結構化錯誤)
適用于需要返回復雜錯誤信息的場景。
#include <string>
#include <variant>
// 定義可能的錯誤類型
struct Error {
int code;
std::string message;
};
// 使用 std::variant 表示可能成功或失敗
template <typename T>
using Result = std::variant<T, Error>;
Result<double> SafeDivide(double a, double b) {
if (b == 0) {
return Error{1, "Division by zero"};
}
return a / b;
}
// 調(diào)用示例:
auto result = SafeDivide(1, 0);
if (std::holds_alternative<Error>(result)) {
auto err = std::get<Error>(result);
std::cerr << "Error " << err.code << ": " << err.message << std::endl;
// 處理錯誤...
}
優(yōu)點:
- 錯誤信息結構化(錯誤碼 + 描述)。
- 適用于需要詳細錯誤信息的 API。
缺點:
- 需要 C++17(std::variant)。
- 比錯誤碼稍復雜。
5. 使用日志記錄(Logging)
適用于調(diào)試或非關鍵錯誤。
#include <iostream>
bool ComputeSomething(int input, double& output) {
if (input < 0) {
std::cerr << "[ERROR] Input must be non-negative" << std::endl;
return false;
}
output = sqrt(input);
return true;
}
// 調(diào)用示例:
double result;
if (!ComputeSomething(-1, result)) {
// 錯誤已打印,無需額外處理
}
優(yōu)點:
簡單直接,適合調(diào)試。
缺點:
錯誤處理不夠靈活(日志可能被忽略)。
最佳實踐建議
- 簡單錯誤 → 使用 std::optional 或錯誤碼。
- 關鍵錯誤 → 使用異常(如文件無法打開、內(nèi)存不足)。
- 復雜錯誤 → 使用 std::expected(C++23)或自定義 Result 類型。
- 調(diào)試/日志 → 結合日志記錄(如 spdlog 或 std::cerr)。
你的選擇應該基于:
- 性能需求(異常 vs 錯誤碼)。
- 錯誤嚴重程度(可恢復 vs 不可恢復)。
- 代碼可讀性(結構化錯誤 vs 簡單錯誤碼)。
到此這篇關于C/C++中函數(shù)分裝時錯誤處理的常見方法的文章就介紹到這了,更多相關C/C++錯誤處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C語言切割多層字符串(strtok_r strtok使用方法)
這篇文章主要介紹了C語言切割多層字符串的方法,說了strtok的弱點,使用strtok_r的方法2013-11-11
解析如何用指針實現(xiàn)整型數(shù)據(jù)的加法
本篇文章是對用指針實現(xiàn)整型數(shù)據(jù)加法的方法進行了詳細的分析介紹,需要的朋友參考下2013-05-05

