2021-09-28 07:04:27
自定义C++异常类可通过继承std::exception或其派生类实现,核心目的是提高异常信息的语义性和可识别性,便于区分不同模块或业务逻辑的错误。以下是具体实现步骤和示例:
一、基础实现步骤必须声明为const noexcept,确保异常安全。
返回成员变量(如std::string)的C风格字符串指针(c_str())。
使用示例:
try { throw MyException("这是一个自定义异常");} catch (const std::exception& e) { std::cout << "捕获到异常: " << e.what() << std::endl;}二、扩展功能:添加错误码若需结构化数据(如错误码),可在异常类中新增成员变量和访问方法:
class MyErrorCodeException : public std::exception {private: std::string msg; int errorCode;public: MyErrorCodeException(const std::string& message, int code) : msg(message), errorCode(code) {} const char* what() const noexcept override { return msg.c_str(); } int code() const noexcept { // 新增错误码访问方法 return errorCode; }};使用示例:
try { throw MyErrorCodeException("数据库连接失败", 1001);} catch (const MyErrorCodeException& e) { std::cout << "错误码:" << e.code() << ", 描述:" << e.what() << std::endl;}三、设计异常类层级结构对于多模块项目,建议设计异常类层级,便于按需捕获:
// 基类class BaseException : public std::exception {public: virtual const char* what() const noexcept = 0;};// 子类:网络模块异常class NetworkException : public BaseException {private: std::string msg;public: explicit NetworkException(const std::string& message) : msg(message) {} const char* what() const noexcept override { return msg.c_str(); }};// 子类:文件模块异常class FileException : public BaseException {private: std::string msg;public: explicit FileException(const std::string& message) : msg(message) {} const char* what() const noexcept override { return msg.c_str(); }};使用示例:
try { // 模拟网络错误 throw NetworkException("网络超时");} catch (const NetworkException& e) { std::cout << "网络错误: " << e.what() << std::endl;} catch (const FileException& e) { std::cout << "文件错误: " << e.what() << std::endl;}四、关键注意事项避免返回局部变量指针:what()中返回的字符串必须来自成员变量或静态字符串,否则会导致未定义行为。
// 错误示例:返回局部变量指针const char* what() const noexcept override { std::string temp = "临时错误"; return temp.c_str(); // 错误!temp离开作用域后指针失效}避免复杂资源管理:异常类中不应包含文件操作、内存分配等可能抛出异常的逻辑,防止二次异常。
优先使用标准库派生类:若异常属于逻辑错误(如参数无效),可继承std::logic_error;运行时错误(如文件不存在)继承std::runtime_error。
通过以上方法,可实现清晰、可维护的自定义异常系统,提升代码的健壮性和可调试性。