You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何规范组织与编写基于std::exception的项目自定义异常类?

用宏快速创建自定义异常类(继承std::runtime_error)

嘿,你这个用宏批量生成自定义异常类的思路很实用啊,刚好适配项目里多种异常场景的需求!我帮你补全并优化这个实现,再给你讲讲具体怎么用:

首先是完整的宏定义代码,我补充了std::string类型的构造函数,让使用更灵活:

#include <stdexcept>
#include <string>

// 宏定义:快速生成继承自std::runtime_error的自定义异常类
#define MYEXCEPTION(exception_name) \
struct exception_name : public ::std::runtime_error { \
    typedef ::std::runtime_error Base; \
    // 支持C风格字符串参数
    explicit exception_name(const char* msg) : Base(msg) {} \
    // 支持std::string参数
    explicit exception_name(const std::string& msg) : Base(msg) {} \
};

针对项目场景生成对应异常类

根据你提到的文件读写、数据转换、成员创建等场景,我们可以快速生成专属异常:

  • 文件读写相关异常
MYEXCEPTION(FileOpenError)    // 文件打开失败
MYEXCEPTION(FileReadError)    // 文件读取失败
MYEXCEPTION(FileWriteError)   // 文件写入失败
  • 数据类型转换/读取相关异常
MYEXCEPTION(TypeConvertError)     // 类型转换失败
MYEXCEPTION(DataParseError)       // 数据解析错误
MYEXCEPTION(InvalidDataFormat)    // 数据格式无效
  • 成员创建相关异常
MYEXCEPTION(MemberInitFailed)     // 成员初始化失败
MYEXCEPTION(InvalidMemberConfig)  // 成员配置无效

代码中抛出与捕获异常示例

抛出异常

void load_user_data(const std::string& filename) {
    FILE* file = fopen(filename.c_str(), "r");
    if (!file) {
        // 拼接错误信息后抛出
        throw FileOpenError("Failed to open user data file: " + filename);
    }
    // ... 后续读取操作,若解析失败可抛出DataParseError
}

捕获异常

int main() {
    try {
        load_user_data("user_info.dat");
    } catch (const FileOpenError& e) {
        // 精准捕获文件打开异常
        std::cerr << "[File Error] " << e.what() << std::endl;
    } catch (const DataParseError& e) {
        // 精准捕获数据解析异常
        std::cerr << "[Parse Error] " << e.what() << std::endl;
    } catch (const std::runtime_error& e) {
        // 兜底捕获所有继承自runtime_error的异常
        std::cerr << "[Runtime Error] " << e.what() << std::endl;
    } catch (...) {
        // 捕获未知异常
        std::cerr << "[Unknown Error] An unexpected error occurred" << std::endl;
    }
    return 0;
}

扩展建议:携带更多异常信息

如果需要异常携带额外信息(比如错误码、发生异常的行号),可以扩展宏的定义:

#define MYEXCEPTION_WITH_DETAILS(exception_name) \
struct exception_name : public ::std::runtime_error { \
    typedef ::std::runtime_error Base; \
    int error_code; \
    int line_num; \
    exception_name(const std::string& msg, int code, int line) \
        : Base(msg), error_code(code), line_num(line) {} \
};

// 使用示例:抛出带错误码和行号的异常
MYEXCEPTION_WITH_DETAILS(FileReadError)
throw FileReadError("Failed to read file header", 2001, __LINE__);

这样你就能根据项目需求灵活生成不同类型的自定义异常类啦!

内容的提问来源于stack exchange,提问作者M.Jane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:50:17