什么是C++异常处理?
C++ 异常处理是一种机制,用于在程序运行过程中处理可能发生的错误或异常情况。当发生异常时,程序会跳出当前的执行流程,并查找能够处理该异常的代码块,执行相应的处理逻辑,从而避免程序崩溃或产生未定义行为。
异常可以是由系统抛出的(如内存分配失败)或由程序员主动抛出的(如检测到输入错误)。C++ 中的异常处理机制主要包括以下几个部分:
-
异常的抛出:使用
throw
关键字抛出异常对象。 -
异常的捕获:使用
try-catch
块捕获异常,并执行相应的处理逻辑。 -
异常的处理:在 catch 块中,可以对捕获到的异常进行处理,包括输出异常信息、记录日志、重新抛出异常或返回默认值等。
-
异常的传递:如果异常没有被捕获,它会在调用栈中继续向上抛出,直到遇到能够处理异常的代码块。
异常处理能够增强程序的健壮性和可靠性,使得程序能够更好地应对异常情况并进行相应的处理。
C++ 异常处理的案例
以下是一些使用 C++ 异常处理的案例:
数组越界异常处理
#include <iostream>
#include <stdexcept>
int main() {
int arr[3] = {1, 2, 3};
try {
int val = arr[5];
} catch(const std::out_of_range& e) {
std::cout << "数组越界异常:" << e.what() << std::endl;
}
return 0;
}
文件打开异常处理
#include <iostream>
#include <fstream>
#include <stdexcept>
int main() {
std::ifstream file;
try {
file.open("nonexistent.txt");
if (!file.is_open()) {
throw std::runtime_error("文件打开失败");
}
// 其他文件操作
file.close();
} catch(const std::exception& e) {
std::cout << "异常:" << e.what() << std::endl;
}
return 0;
}
自定义异常类
#include <iostream>
#include <stdexcept>
class MyException : public std::exception {
public:
MyException(const char* message) : m_message(message) {}
virtual const char* what() const noexcept {
return m_message;
}
private:
const char* m_message;
};
int divide(int numerator, int denominator) {
if (denominator == 0) {
throw MyException("除数不能为零");
}
return numerator / denominator;
}
int main() {
try {
int result = divide(10, 0);
} catch(const MyException& e) {
std::cout << "自定义异常:" << e.what() << std::endl;
}
return 0;
}
这些示例展示了如何使用 C++ 异常处理来处理各种异常情况,保护代码免受错误的影响,并提供适当的错误信息。
stdexcept
标准库
stdexcept
是 C++ 标准库中的头文件,其中定义了一些常见的异常类。它提供了一组用于常见异常类型的类,这些异常类是从 std::exception
类派生而来的。
以下是 stdexcept
头文件中定义的异常类和使用案例:
std::logic_error
异常类
-
std::logic_error
是一个基类,用于派生针对逻辑错误的异常类,如std::invalid_argument
和std::length_error
。 -
示例:
#include <iostream> #include <stdexcept> int main() { try { throw std::logic_error("逻辑错误"); } catch(const std::logic_error& e) { std::cout << "逻辑错误异常:" << e.what() << std::endl; } return 0; }
std::invalid_argument
异常类
-
std::invalid_argument
表示传递给函数的参数无效。 -
示例:
#include <iostream> #include <stdexcept> int divide(int numerator, int denominator) { if (denominator == 0) { throw std::invalid_argument("除数不能为零"); } return numerator / denominator; } int main() { try { int result = divide(10, 0); } catch(const std::invalid_argument& e) { std::cout << "无效参数异常:" << e.what() << std::endl; } return 0; }
std::length_error
异常类
-
std::length_error
表示长度错误,例如字符串长度超出限制。 -
示例:
#include <iostream> #include <stdexcept> int main() { try { std::string str(1000000000, 'a'); // 创建一个长度为 1,000,000,000 的字符串 } catch(const std::length_error& e) { std::cout << "长度错误异常:" << e.what() << std::endl; } return 0; }
std::out_of_range
异常类
-
std::out_of_range
表示索引超出范围,例如数组越界或迭代器越界。 -
示例:
#include <iostream> #include <stdexcept> int main() { try { std::vector<int> vec = {1, 2, 3}; int value = vec.at(5); // 索引超出范围 } catch(const std::out_of_range& e) { std::cout << "索引超出范围异常:" << e.what() << std::endl; } return 0; }
通过使用 stdexcept
中定义的异常类,可以更方便地创建和处理常见的异常情况,提供有用的错误信息,并帮助代码更健壮地处理异常。