使用try-catch捕获指定异常类型,按引用捕获避免切片,自定义异常应继承std::exception,捕获顺序需从具体到通用,确保异常处理精准高效。

在C++中,捕获指定的异常类型需要使用try-catch语句块,并在catch子句中明确写出要捕获的异常类型。通过这种方式,可以针对不同类型的异常分别处理,提高程序的健壮性和可维护性。
捕获特定异常类型的基本语法
使用catch关键字后跟具体的异常类型(如std::invalid_argument、std::out_of_range等),即可捕获该类型的异常:
try {
// 可能抛出异常的代码
throw std::invalid_argument("参数无效");
}
catch (const std::invalid_argument& e) {
// 专门处理 invalid_argument 异常
std::cout << "捕获到 invalid_argument: " << e.what() << std::endl;
}
catch (const std::out_of_range& e) {
// 专门处理 out_of_range 异常
std::cout << "捕获到 out_of_range: " << e.what() << std::endl;
}
按引用捕获避免 slicing 问题
建议始终以const 引用方式捕获标准异常或自定义异常对象:
- 防止对象切片(slicing):若按值捕获派生类异常,可能丢失派生部分信息。
- 避免不必要的拷贝,提升性能。
-
标准库异常通常支持多态,引用能正确调用
what()等虚函数。
catch (const std::exception& e) {
std::cout << "通用异常信息: " << e.what() << std::endl;
}
处理自定义异常类型
你可以定义自己的异常类并捕获它:
立即学习“C++免费学习笔记(深入)”;
struct MyException {
std::string msg;
MyException(const std::string& s) : msg(s) {}
};
try {
throw MyException("自定义错误");
}
catch (const MyException& e) {
std::cout << "捕获自定义异常: " << e.msg << std::endl;
}
注意:自定义异常最好继承自std::exception或其子类,以便与标准异常体系兼容。
异常捕获顺序的重要性
多个catch块按书写顺序匹配,因此更具体的异常应放在前面:
try {
// ...
}
catch (const std::domain_error& e) { // 具体类型,放前面
// 处理 domain_error
}
catch (const std::logic_error& e) { // 基类,放后面
// 处理其他 logic_error
}
catch (const std::exception& e) { // 更通用,最后
// 处理所有其他标准异常
}
如果把基类写在前面,派生类将永远不会被匹配到。
基本上就这些。合理使用特定异常捕获,能让错误处理更精准、调试更容易。










