异常是带类型、可调度的活对象,通过泛型集合收纳、多态分发与虚函数绑定实现统一处理,无需if-else或多重catch。

初学阶段不用纠结“多态泛型流”这个合成词,它实际指向一个清晰动作:把异常看作有类型、能分类、可调度的对象,再用泛型集合装起来,靠多态机制自动分发处理——整个过程就是异常从生成、上浮、匹配到执行的完整脉络。
异常不是消息,是带身份的活对象
throw new FileOpenException("path not found") 不是一句报错提示,而是在内存里创建了一个真实对象。它有明确类型(FileOpenException),有父类链(→ IOException → Exception),还有自己的字段(比如错误路径、时间戳)。这个对象一诞生,就带着全部身份信息开始向上冒泡,就像快递包裹贴着“易碎”“冷链”标签走分拣线。
- 不抛异常时,程序顺序执行,像流水线匀速运转
- 一执行 throw,当前函数立刻中断,对象生成并启动“向上找 handler”的旅程
- 调用链 funcA → funcB → funcC 中,funcC 抛出,先查自己有没有 catch;没有,就交 funcB;再没有,交 funcA——这不是静态配置,而是运行时按对象实际类型动态匹配
用泛型集合统一收纳,不丢失类型细节
定义 List
- 收集时不需 if 判断类型,直接 add,编译器自动完成向上转型
- 遍历时调用 e.Handle(),执行的永远是 FileOpenException 重写的逻辑,不是基类空实现
- 新增 NetworkTimeoutException?只需写子类+重写 Handle,原集合和循环代码完全不动
靠虚函数绑定,让同一句调用触发不同行为
在 BaseException 中声明 virtual void Handle(),各子类分别实现:
- FileOpenException.Handle() → 弹窗提示路径,并打开文件选择器
- DivideByZeroException.Handle() → 记录日志,建议用户检查输入值
- MemoryAllocException.Handle() → 触发 GC,延迟重试
catch 块里只写一次 catch(BaseException& e) { e.Handle(); },就完成了对所有子类的统一调度。不用 if-else 查 e.GetType(),也不用维护一堆 catch 分支。
用字典做类型路由,适配复杂分发场景
当处理逻辑差异大、不适合全塞进 Handle 时,可用 Dictionary
- handlers[typeof(FileOpenException)] = e => ShowFileDialog(e.Message);
- handlers[typeof(NetworkTimeoutException)] = e => RetryWithBackoff();
捕获后一行代码就能跳转:handlers[e.GetType()](e)。这比硬编码 switch 更灵活,也比层层嵌套 if 更易维护。
不复杂但容易忽略:异常脉络的清晰,不来自堆砌语法,而来自把“类型”“行为”“容器”三者真正联动起来——对象有身份,集合能收纳,虚函数会分发,字典可扩展。











