在C++程序开发中,标准库提供的std::exception及其派生类能够覆盖部分通用异常场景,但实际业务里往往需要更贴合具体场景的异常类型,比如网络请求失败、配置解析错误等场景,此时就需要自定义异常类。继承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::string的c_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