一、基本概念
异常(Exception):程序执行过程中发生的非正常情况,比如除以零、访问越界、内存不足等。
异常处理(Exception Handling):对异常情况进行捕获、分析,并采取补救措施,防止程序崩溃。
C++ 采用 try-catch 语句块配合 throw 来实现异常处理:
try 块:放置可能抛出异常的代码。
throw:用于抛出异常对象。
catch 块:用于捕获异常并处理。
二、语法结构
try {// 可能抛出异常的代码if (something_wrong) {throw exception_object; // 抛出异常}
}
catch (ExceptionType1 e1) {// 处理 ExceptionType1 类型的异常
}
catch (ExceptionType2 e2) {// 处理 ExceptionType2 类型的异常
}
catch (...) {// 捕获所有未明确捕获的异常
}
throw 后面可以是任意类型:内置类型(如 int)、字符串、用户自定义类等。
catch 块会根据异常的类型选择匹配的处理器。
catch (…) 是通配符,表示捕获所有未被前面 catch 捕获的异常。
注:
- 推荐抛出类或结构体:最好抛出异常类,而不是基础类型,比如用 std::runtime_error、std::invalid_argument、std::out_of_range 等。
- 按引用捕获:为了避免拷贝,catch 中最好用引用捕获异常。
- 异常必须处理:如果异常未被捕获,程序会调用 std::terminate(),导致程序异常终止。
- 嵌套异常与重新抛出:可以在 catch 里再次 throw 把异常往外传递。
三、异常示例
小试牛刀:
#include <iostream>
#include <stdexcept> // 引入标准异常头文件using namespace std;int divide(int a, int b) {if (b == 0) {throw runtime_error("Division by zero!"); // 抛出标准运行时异常}return a / b;
}int main() {try {int result = divide(10, 0); // 这里会抛出异常cout << "Result: " << result << endl;} catch (const runtime_error& e) { // 用引用捕获标准异常cout << "Caught exception: " << e.what() << endl;}cout << "Program continues..." << endl;return 0;
}
输出结果:
工程中常见的处理
#include <iostream>
#include <stdexcept>
#include <string>using namespace std;// 错误码枚举
enum class ErrorCode {InvalidArgument = 1001,ZeroValue = 1002,OutOfRange = 1003
};// 自定义异常类
class MyError : public exception {
private:string message;ErrorCode code;string file;int line;public:MyError(const string& msg, ErrorCode c, const string& f, int l): message(msg), code(c), file(f), line(l) {}// 重写 what() 方法,返回错误信息const char* what() const noexcept override {return message.c_str();}ErrorCode getCode() const noexcept {return code;}const string& getFile() const noexcept {return file;}int getLine() const noexcept {return line;}
};// 用宏封装 throw,自动带文件名和行号
#define THROW_MYERROR(msg, code) throw MyError(msg, code, __FILE__, __LINE__)// 抛异常的函数
void doSomething(int value) {if (value < 0) {THROW_MYERROR("Value must be non-negative!", ErrorCode::InvalidArgument);} else if (value == 0) {THROW_MYERROR("Value must not be zero!", ErrorCode::ZeroValue);} else if (value > 100) {THROW_MYERROR("Value out of valid range!", ErrorCode::OutOfRange);}cout << "doSomething succeeded." << endl;
}int main() {try {doSomething(-5); // 会触发 InvalidArgument}catch (const MyError& e) {cout << "Caught MyError: " << e.what() << endl;cout << "Error code: " << static_cast<int>(e.getCode()) << endl;cout << "File: " << e.getFile() << endl;cout << "Line: " << e.getLine() << endl;}cout << "Program continues..." << endl;return 0;
}
输出结果: