C++关于手动抛出异常,自动抛出异常以及一些不会抛出异常的情况说明

异常的抛出方式主要包含显式抛出,一些库在运行时抛出以及一些未定义的行为可能直接导致程序崩溃的情况,下面将在这篇文章中分别进行说明:


1. 显式抛出throw 关键字)

这是我们说的「自己抛出的」异常。

cpp 复制代码
#include <stdexcept>
#include <iostream>

void test() {
    throw std::runtime_error("manual error");
}

int main() {
    try {
        test();
    } catch (const std::exception& e) {
        std::cout << "Caught: " << e.what() << '\n';
    }
}

输出:

复制代码
Caught: manual error

这种情况是程序员主动throw 抛出异常。很多自定义异常类、手动检查逻辑都是这么做的。


2. 由库/运行时产生的异常

即使你没有显式使用 throw ,某些库函数或运行时也会在错误条件下自动抛出异常

例 1:标准库越界访问抛出异常

cpp 复制代码
#include <vector>
#include <iostream>
#include <stdexcept>

int main() {
    std::vector<int> v = {1, 2, 3};

    try {
        int x = v.at(5); // at() 会检查索引范围,越界时抛出 std::out_of_range
    } catch (const std::out_of_range& e) {
        std::cout << "Caught: " << e.what() << '\n';
    }
}

输出例子(取决于实现):

复制代码
Caught: vector::_M_range_check: __n (which is 5) >= this->size() (which is 3)

注意

这里你没有写 throw,但是 v.at() 内部在发现越界条件时会自动执行 throw std::out_of_range


例 2:new 分配失败抛出异常

cpp 复制代码
#include <iostream>
#include <new> // std::bad_alloc

int main() {
    try {
        // 故意申请一个极大数量的内存
        int* p = new int[1'000'000'000'000];
        delete[] p;
    } catch (const std::bad_alloc& e) {
        std::cout << "Memory allocation failed: " << e.what() << '\n';
    }
}

输出:

复制代码
Memory allocation failed: std::bad_alloc

这是 运行时系统 在内存不足时自动抛出的 std::bad_alloc


例 3:某些运算也可能抛出异常

严格意义上 算术运算本身(如整数除以0)不会抛出标准 C++ 异常 ,而是导致未定义行为(多数平台直接程序崩溃)。

但如果你使用了一些安全数学类、智能数值库,它们可能会检查并主动 throw


3. try-catch 并不会「自动抛异常」

try只是捕捉 从其范围内抛出的异常,本身不会触发抛出。

是否会发生异常,要看:

  • 代码中是否显式 throw
  • 被调用的库函数或运算是否会自动抛异常(比如 vector::atnew、部分算法)

如果是普通的数组越界访问 arr[10](越过边界),这不会抛出标准异常,而是未定义行为

cpp 复制代码
int arr[3] = {1, 2, 3};
try {
    int x = arr[10]; // 未定义行为,不会抛出异常
} catch (...) {
    std::cout << "This won't catch anything\n";
}

要捕获越界,你必须使用会检查边界并抛异常的接口,比如 std::vector::at()


4. 总结

  • 异常可以是手动 throw 出的,也可以是库或运行时自动抛出的
  • try/catch 不会制造异常,它只是异常捕获机制。
  • 常见自动抛出的场景:
    • std::vector::at() 越界 → std::out_of_range
    • new 分配失败 → std::bad_alloc
    • 标准库里很多算法会在不满足前置条件时 throw
  • 原生数组越界、整数除0 等并不会自动抛标准异常,而是未定义行为。
相关推荐
程序员老舅15 小时前
‌NAT穿透技术原理:P2P通信中的打洞机制解析‌
服务器·c++·网络协议·网络编程·p2p·nat·网络穿透
凤年徐15 小时前
【数据结构】八大排序之快速排序:分而治之的艺术
c语言·开发语言·数据结构·c++·算法·排序算法
啊吧怪不啊吧15 小时前
C++之基于正倒排索引的Boost搜索引擎项目介绍
c++·http·搜索引擎
乔宕一15 小时前
使用 C 模仿 C++ 模板的拙劣方法
c语言·开发语言·c++
Tipriest_15 小时前
什么时候需要使用虚继承,什么是菱形继承
c++·virtual·菱形继承·虚继承
BYSJMG16 小时前
计算机毕设推荐:基于python的农产品价格数据分析与预测的可视化系统的设计与实现 基于Python农产品管理系统【源码+文档+调试】
大数据·开发语言·hadoop·python·数据分析·django·课程设计
火山kim16 小时前
一文速通C#(网页资源版)
开发语言·c#
油炸自行车16 小时前
【Qt】bug排查笔记——QMetaObject::invokeMethod: No such method
c++·笔记·qt·bug
冬天vs不冷16 小时前
Java基础(十):关键字static详解
java·开发语言