C++ 提供了多种错误处理机制,用于在程序中检测和处理异常情况。这些机制包括异常处理、错误返回码、断言(assert)以及其他自定义的错误处理方法。以下是对 C++ 错误处理机制的详细介绍:
1. 异常处理(Exception Handling)
异常处理是 C++ 提供的主要错误处理机制,使用 try
、catch
和 throw
关键字来捕获和处理错误。
基本语法
try {
// 可能抛出异常的代码
if (someErrorCondition) {
throw std::runtime_error("An error occurred");
}
} catch (const std::exception& e) {
// 处理异常
std::cerr << "Caught exception: " << e.what() << std::endl;
}
详细示例
#include <iostream>
#include <stdexcept>
void mightThrow() {
throw std::runtime_error("An unexpected error occurred");
}
int main() {
try {
mightThrow();
} catch (const std::exception& e) {
std::cerr << "Caught exception: " << e.what() << std::endl;
}
return 0;
}
自定义异常类
#include <iostream>
#include <exception>
class MyException : public std::exception {
public:
const char* what() const noexcept override {
return "My custom exception occurred";
}
};
void functionThatThrows() {
throw MyException();
}
int main() {
try {
functionThatThrows();
} catch (const MyException& e) {
std::cerr << "Caught custom exception: " << e.what() << std::endl;
}
return 0;
}
2. 错误返回码
使用返回码是另一种常见的错误处理方法,特别是在异常开销不合适的情况下。通过函数返回值指示错误,并在调用处检查这些返回值。
示例
#include <iostream>
enum class ErrorCode {
SUCCESS,
ERROR_DIVIDE_BY_ZERO
};
ErrorCode divide(int a, int b, int& result) {
if (b == 0) {
return ErrorCode::ERROR_DIVIDE_BY_ZERO;
}
result = a / b;
return ErrorCode::SUCCESS;
}
int main() {
int result;
ErrorCode code = divide(10, 0, result);
if (code == ErrorCode::ERROR_DIVIDE_BY_ZERO) {
std::cerr << "Error: Division by zero" << std::endl;
} else {
std::cout << "Result: " << result << std::endl;
}
return 0;
}
3. 断言(Assert)
断言用于在调试阶段捕捉不可恢复的错误。它在条件为假时终止程序执行并打印错误信息。适用于开发阶段的调试。
示例
#include <iostream>
#include <cassert>
int divide(int a, int b) {
assert(b != 0); // 确保除数不为零
return a / b;
}
int main() {
int result = divide(10, 2);
std::cout << "10 / 2 = " << result << std::endl;
// 这行代码将触发 assert,因为 b 为 0
result = divide(10, 0);
std::cout << "10 / 0 = " << result << std::endl;
return 0;
}
4. 日志记录
日志记录是一种监控和记录错误发生情况的方法,常用于生产环境中进行故障排查。
示例
#include <iostream>
#include <fstream>
#include <stdexcept>
void logError(const std::string& message) {
std::ofstream logFile("error.log", std::ios_base::app);
logFile << message << std::endl;
}
void functionThatMightFail() {
throw std::runtime_error("An error occurred");
}
int main() {
try {
functionThatMightFail();
} catch (const std::exception& e) {
logError(e.what());
std::cerr << "Caught exception: " << e.what() << std::endl;
}
return 0;
}
5. 条件检查和防御性编程
通过条件检查在运行时防止错误发生,例如参数验证。
示例
#include <iostream>
void processInput(int input) {
if (input < 0) {
std::cerr << "Error: input must be non-negative" << std::endl;
return;
}
// 处理输入
}
int main() {
processInput(-1);
processInput(10);
return 0;
}
6. 总结
- 异常处理:用于捕获和处理运行时错误,适合处理不可预见的异常情况。
- 错误返回码:适用于函数调用链中明确的错误检查,常用于嵌入式系统和性能敏感的代码。
- 断言:用于开发阶段捕捉编程错误,发布版本通常禁用。
- 日志记录:用于记录和追踪错误,帮助调试和维护。
- 条件检查和防御性编程:通过提前检查条件防止错误发生。
根据具体情况和需求,选择适合的错误处理机制可以提高程序的健壮性和可维护性。