C++如何自定义异常类_C++继承exception类实现异常处理【扩展】

14次阅读

继承 std::exception 是为了接入标准异常体系,支持统一捕获、多态和扩展;必须重写 what() 并加 noexcept,返回长期有效的 const char*;额外信息通过成员变量和访问器携带。

C++ 如何自定义异常类_C++ 继承 exception 类实现异常处理【扩展】

为什么 继承 std::exception 而不是直接用字符串 throw?

直接 throw "error"throw 42 虽然语法合法,但无法统一捕获类型、丢失上下文、且不能携带额外信息(如错误码、文件名、行号)。继承 std::exception 是为了接入标准异常体系:能被 catch (const std::exception& e) 捕获,支持多态,也方便后续扩展字段和重载 what()

自定义异常类必须重写 what() 吗?

是的。基类 std::exception::what() 返回的是空字符串或未定义行为;不重写会导致 e.what() 输出不可靠内容(常见为 "std::exception" 或崩溃)。实际中要确保返回指向 ** 长期有效内存 ** 的 const char*

  • 不能返回局部数组(如 char buf[256]; return buf;
  • 不能返回临时 std::stringc_str()(如 return std::string("xxx").c_str();
  • 推荐用 mutable std::string m_what_cache 缓存,每次调用 what() 时更新并返回其 c_str()

示例关键片段:

class FileOpenError : public std::exception {std::string m_msg; public:     FileOpenError(const std::string& file)          : m_msg("Failed to open file:" + file) {}     const char* what() const noexcept override {return m_msg.c_str();     } };

要不要加 noexcept 修饰 what()

要。C++11 起,std::exception::what() 声明为 noexcept,子类重写时若不加,会隐式变成可能抛异常,导致编译警告甚至 ABI 不兼容(尤其在动态链接场景)。所有重写的 what() 必须带 noexcept

立即学习C++ 免费学习笔记(深入)”;

  • 漏写 noexcept 可能触发 GCC/Clang 的 -Wexceptions 警告
  • 某些 STL 实现(如 libc++)在异常传播中会检查 what() 是否 noexcept,否则行为未定义

如何携带错误码、位置信息等额外字段?

标准 std::exception 不提供扩展接口,所以靠成员变量 + 公共访问器。常见做法:

  • 添加 int m_errno(如系统调用失败时保存 errno
  • 添加 const char* m_fileint m_line,通过宏封装构造:throw MyError("msg", __FILE__, __LINE__)
  • 避免在 what() 中拼接耗时操作(如格式化时间戳),只做轻量字符串组合

注意:这些字段不影响 catch 匹配逻辑,仅用于日志或调试输出。

复杂点在于缓存 what() 返回值的生命周期管理——多数人卡在临时对象析构后还去访问 c_str(),结果是随机字符或段错误。

text=ZqhQzanResources