导读:本期聚焦于小伙伴创作的《如何自定义C++异常类 继承std exception的最佳实践》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何自定义C++异常类 继承std exception的最佳实践》有用,将其分享出去将是对创作者最好的鼓励。

在C++程序开发中,标准库提供的std::exception及其派生类能够覆盖部分通用异常场景,但实际业务里往往需要更贴合具体场景的异常类型,比如网络请求失败、配置解析错误等场景,此时就需要自定义异常类。继承std::exception是实现自定义异常的标准做法,遵循最佳实践能够让异常类更规范,也更容易和其他代码兼容。

如何自定义C++异常类 继承std exception的最佳实践

为什么选择继承std::exception

std::exception是所有标准异常的基类,定义了异常的核心接口,继承它能够让自定义异常融入C++的标准异常处理体系。当使用catch(const std::exception& e)捕获异常时,自定义异常也能被正常捕获,不需要额外编写特殊的捕获逻辑,降低了代码的耦合度。

继承std::exception的核心要求

自定义异常类继承std::exception时,需要遵循几个核心规范,才能保证类的可用性:

  • 必须重写what()方法,该方法返回异常的描述信息,是std::exception定义的纯虚函数,返回值类型为const char*
  • 构造函数需要支持传入自定义异常信息,方便在抛出异常时携带具体的错误原因
  • 异常信息需要妥善存储,避免返回悬垂指针,通常可以使用std::string存储,也可以在简单场景下使用静态字符串
  • 建议添加虚析构函数,虽然std::exception本身有虚析构函数,但显式声明可以让代码逻辑更清晰

最佳实践实现示例

下面是一个符合规范的自定义异常类实现,以网络异常为例:

#include <exception>
#include <string>
#include <cstring>

// 自定义网络异常类,继承std::exception
class NetworkException : public std::exception {
private:
    std::string err_msg; // 存储异常信息
public:
    // 构造函数,支持传入自定义错误信息
    explicit NetworkException(const std::string& msg) : err_msg(msg) {}

    // 重写what()方法,返回异常描述
    const char* what() const noexcept override {
        return err_msg.c_str();
    }

    // 虚析构函数,符合异常类的设计规范
    ~NetworkException() noexcept override = default;
};

如果需要更轻量的实现,不需要动态存储异常信息,也可以使用静态字符串的方式:

#include <exception>

class ConfigParseException : public std::exception {
private:
    const char* err_msg;
public:
    // 构造函数,默认错误信息或使用传入的信息
    explicit ConfigParseException(const char* msg = "配置文件解析失败") : err_msg(msg) {}

    const char* what() const noexcept override {
        return err_msg;
    }

    ~ConfigParseException() noexcept override = default;
};

使用示例

自定义异常类实现后,可以在业务代码中抛出和捕获:

#include <iostream>
#include <exception>

// 假设上面的NetworkException类定义在这里

void send_request() {
    // 模拟网络请求失败场景
    bool request_success = false;
    if (!request_success) {
        throw NetworkException("连接远程服务器超时,请检查网络");
    }
}

int main() {
    try {
        send_request();
    } catch (const std::exception& e) {
        // 可以捕获所有继承std::exception的异常,包括自定义的NetworkException
        std::cout << "捕获到异常:" << e.what() << std::endl;
    } catch (...) {
        std::cout << "捕获到未知异常" << std::endl;
    }
    return 0;
}

常见误区提醒

  • 不要在what()方法里返回局部变量的指针,比如返回函数内临时std::stringc_str(),会导致悬垂指针问题
  • 不要忽略noexcept修饰符,what()方法和析构函数都应该标记为noexcept,符合标准异常的行为规范
  • 不要随意添加不必要的成员变量和方法,自定义异常类的核心作用是传递异常信息,保持简洁即可
  • 如果需要区分不同的异常类型,不要仅靠what()返回的信息判断,可以通过定义不同的异常类来实现类型区分,方便catch块针对性处理

扩展场景:带错误码的异常类

有些场景下除了异常描述,还需要携带错误码,可以在自定义异常类中添加错误码成员:

#include <exception>
#include <string>

class DatabaseException : public std::exception {
private:
    std::string err_msg;
    int error_code;
public:
    DatabaseException(const std::string& msg, int code) : err_msg(msg), error_code(code) {}

    const char* what() const noexcept override {
        return err_msg.c_str();
    }

    int get_error_code() const noexcept {
        return error_code;
    }

    ~DatabaseException() noexcept override = default;
};

使用时可以通过get_error_code()方法获取错误码,做更精细的异常处理。

C++自定义异常类std_exception异常处理修改时间:2026-07-05 13:06:13

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。