std::runtime_error用于抛出运行时错误,适用于外部环境或资源异常导致的问题,如文件打开失败、网络超时等,其消息应包含具体上下文以便定位问题。

std::runtime_error 是 C++ 标准库中用于抛出**运行时错误**的异常类,继承自 std::exception,适用于那些无法在编译期检查、只能在程序执行过程中发现的问题(比如文件打开失败、内存分配失败、网络连接超时等)。
什么时候该用 std::runtime_error 而不是其他异常?
它属于 std::exception 的「运行时错误」分支,和 std::logic_error(逻辑错误,如 std::invalid_argument)有明确分工:
-
std::runtime_error:问题出在外部环境或资源状态,程序本身逻辑没问题,但“运气不好”——比如fopen返回nullptr、std::stoi遇到非法字符串、std::thread构造失败 -
std::logic_error及其子类:代码写错了,比如传了负数给只接受正数的函数,这类本该在开发/测试阶段就暴露 - 不要用
std::runtime_error替代assert或参数校验——那是std::invalid_argument的职责
如何正确构造和抛出 std::runtime_error?
它只有一个带 const char* 或 std::string 参数的构造函数,消息内容应包含足够上下文,方便定位问题源头:
throw std::runtime_error("failed to open config file: " + filename);
注意以下几点:
立即学习“C++免费学习笔记(深入)”;
- 推荐用
std::string拼接(C++11 起支持),避免const char*字面量拼接出错 - 不要抛裸指针或自定义结构体——必须是
std::exception或其派生类,否则catch(std::exception&)捕不到 - 消息里尽量包含关键变量值(如文件名、URL、返回码),而不是只写“IO error”这种模糊描述
怎么捕获并处理 std::runtime_error?
通常用 catch(const std::runtime_error& e) 单独处理,或用更宽泛的 catch(const std::exception& e) 统一兜底:
try {
std::ifstream f(filename);
if (!f.is_open()) {
throw std::runtime_error("cannot open " + filename);
}
} catch (const std::runtime_error& e) {
std::cerr << "Runtime error: " << e.what() << '\n';
// 记录日志、降级策略、退出等
}
常见误区:
- 写成
catch(std::runtime_error e)(值传递)——会触发不必要的拷贝,且可能切片;必须用const& - 只
catch(...)后吞掉异常——丢失错误信息,调试困难 - 在析构函数里抛
std::runtime_error——C++11 起默认是noexcept,会导致程序直接调用std::terminate
真正容易被忽略的是:很多标准库函数(如 std::stoi、std::filesystem::create_directory)在失败时**默认不抛 std::runtime_error**,而是设置 errno 或返回错误码。你得自己检查结果并主动抛出——别指望它们替你做。







