使用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) { // 更通用,最后 // 处理所有其他标准异常 }
如果把基类写在前面,派生类将永远不会被匹配到。
基本上就这些。合理使用特定异常捕获,能让错误处理更精准、调试更容易。


