文章目录
c++异常处理机制详解
C++的异常处理机制通过try, catch和throw关键字来实现。它允许程序在运行时捕获和处理错误,而不是直接终止程序。下面是对C++异常处理机制的详细解释:
基本原理
1. try 块
try块用于包围可能抛出异常的代码。它的语法如下:
try {
// 可能抛出异常的代码
}
2. throw 语句
throw语句用于抛出一个异常。它可以抛出任何类型的对象,但通常抛出的是标准异常类或自定义异常类的对象。语法如下:
throw 异常对象;
3. catch 块
catch块用于捕获和处理异常。它紧跟在try块之后,可以有多个catch块来处理不同类型的异常。语法如下:
catch (异常类型& 异常对象) {
// 处理异常的代码
}
示例代码
下面是一个完整的示例,展示了如何使用try, catch和throw来进行异常处理:
#include <iostream>
#include <stdexcept>
void mightGoWrong() {
bool error1 = true;
bool error2 = false;
if (error1) {
throw std::runtime_error("Something went wrong");
}
if (error2) {
throw std::exception();
}
}
int main() {
try {
mightGoWrong();
} catch (const std::runtime_error& e) {
std::cerr << "Runtime error: " << e.what() << std::endl;
} catch (const std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
std::cout << "Program continues..." << std::endl;
return 0;
}
在这个示例中:
-
mightGoWrong函数可能会抛出两种不同的异常。
-
在main函数中,使用try块来调用mightGoWrong函数。
-
如果mightGoWrong抛出异常,catch块会捕获并处理这些异常。
-
catch块可以根据异常类型进行不同的处理。
C++中自定义异常类
#include <iostream>
#include <stdexcept>
// 自定义异常类
class MyCustomException : public std::exception {
public:
MyCustomException(const std::string& message) : msg_(message) {}
virtual const char* what() const noexcept override {
return msg_.c_str();
}
private:
std::string msg_;
};
void mightGoWrong() {
bool error1 = true;
bool error2 = false;
if (error1) {
throw std::runtime_error("Runtime error occurred");
}
if (error2) {
throw MyCustomException("Custom error occurred");
}
}
int main() {
try {
mightGoWrong();
} catch (const std::runtime_error& e) {
std::cerr << "Caught runtime error: " << e.what() << std::endl;
} catch (const MyCustomException& e) {
std::cerr << "Caught custom exception: " << e.what() << std::endl;
} catch (const std::exception& e) {
std::cerr << "Caught exception: " << e.what() << std::endl;
}
std::cout << "Program continues..." << std::endl;
return 0;
}
详细解释
-
try块:mightGoWrong函数被放在try块中,因为它可能抛出异常。
-
throw语句:在mightGoWrong函数中,根据条件抛出不同类型的异常。
-
catch块:有多个catch块来捕获不同类型的异常。每个catch块处理特定类型的异常,并输出相应的错误信息。
捕获所有异常
你还可以使用一个通用的catch块来捕获所有类型的异常:
catch (...) {
std::cerr << "Caught an unknown exception" << std::endl;
}
重新抛出异常
在某些情况下,你可能需要在捕获异常后重新抛出它:
catch (const std::exception& e) {
std::cerr << "Caught exception: " << e.what() << std::endl;
throw; // 重新抛出异常
}
在自定义异常类中添加更多的上下文信息
在自定义异常类中添加更多的上下文信息可以帮助你在捕获异常时提供更详细的错误信息。你可以通过添加更多的成员变量和方法来实现这一点。下面是一个示例,展示了如何在自定义异常类中添加更多的上下文信息。
定义自定义异常类
首先,定义一个自定义异常类,并添加更多的上下文信息,例如错误代码、文件名和行号。
#include <exception>
#include <string>
class MyCustomException : public std::exception {
public:
MyCustomException(const std::string& message, int errorCode, const std::string& file, int line)
: msg_(message), errorCode_(errorCode), file_(file), line_(line) {}
virtual const char* what() const noexcept override {
return msg_.c_str();
}
int getErrorCode() const {
return errorCode_;
}
std::string getFile() const {
return file_;
}
int getLine() const {
return line_;
}
private:
std::string msg_;
int errorCode_;
std::string file_;
int line_;
};
使用自定义异常类
在代码中使用throw语句抛出自定义异常,并在catch块中捕获和处理它。
#include <iostream>
#include <fstream>
#include "MyCustomException.h" // 假设自定义异常类定义在这个头文件中
void readFile(const std::string& filename) {
std::ifstream file(filename);
if (!file.is_open()) {
throw MyCustomException("Failed to open file: " + filename, 1001, __FILE__, __LINE__);
}
// 读取文件内容的代码...
}
int main() {
try {
readFile("nonexistent_file.txt");
} catch (const MyCustomException& e) {
std::cerr << "Caught custom exception: " << e.what() << std::endl;
std::cerr << "Error Code: " << e.getErrorCode() << std::endl;
std::cerr << "File: " << e.getFile() << std::endl;
std::cerr << "Line: " << e.getLine() << std::endl;
} catch (const std::exception& e) {
std::cerr << "Caught standard exception: " << e.what() << std::endl;
} catch (...) {
std::cerr << "Caught unknown exception" << std::endl;
}
std::cout << "Program continues..." << std::endl;
return 0;
}
详细解释
- 定义自定义异常类:MyCustomException类继承自std::exception,并添加了错误代码、文件名和行号等成员变量。
- 抛出自定义异常:在readFile函数中,如果文件打开失败,抛出一个MyCustomException异常,并提供详细的上下文信息。
- 捕获自定义异常:在main函数中,使用catch块捕获并处理MyCustomException异常,并输出详细的错误信息。