当前位置: 首页 > news >正文

[C++]错误码与Try-catch

💎个人主页:星柚程

🚀精选文章:《MATLAB多目标优化》,《Kaggle:CV、Public LB 》、《我的第一次 Kaggle》、《C++构造传参》、《蛇形机械臂的模拟退火优化》

🛠️专栏建设:|深度学习|、|Python量化|、|C++学习|、|数据结构|

🎯流水不争先,争得是涛涛不绝。

引言

对于无法在本地恢复、需要向上传播或由统一层处理的异常场景,推荐使用 try-catch。对性能敏感、频繁调用或与 C 接口交互的场合,推荐使用错误码或 std::optional/std::expected 等显式返回策略。

详细解析

异常(try-catch)方式

优点

将错误处理与业务逻辑分离,主流程更简洁;

可以跨多个调用层级向上传播错误,无需每层都检查返回值;

标准库和许多现代库(如<filesystem>、std::thread)都使用异常报告错误。

缺点

性能开销:抛出和捕获异常代价较高,不宜在热路径或频繁错误场景使用;

控制流不直观:过度依赖异常可能让代码阅读和调试更难;

需要在项目中统一规范,否则不同模块混用容易遗漏捕获。

适用场景

系统初始化失败、配置文件解析失败、资源分配失败等“异常”情况;

业务逻辑中确实无法就地处理的错误,需要由上层统一拦截并处理。

错误码 / 显式返回

优点

开销小,调用者直接通过返回值判断并处理;

流程清晰,调用者立刻看到可能的错误分支;

易于与 C 接口或性能敏感代码混用。

缺点

业务逻辑容易被大量的if (err) return err;打断,可读性下降;

容易忽略错误码检查,导致隐性错误。

改进方式

使用enum class ErrorCode或std::error_code进行类型安全的错误码;

C++23 引入std::expected<T, E>,可同时携带返回值和错误信息,简化处理。

适用场景

性能关键的底层库、频繁调用的循环体、跨语言边界(C/C++ 混编);

简单的验证或业务分支(如查找不到元素时返回nullptr或错误码)。

混合使用与团队规范

在同一项目或模块中选择一种主要方式并制定规范;

对于公共接口,若库面向 C++ 用户且错误较少、复杂度高,可用异常;若面向 C 用户或嵌入式场景,则用错误码;

内部实现可用错误码,接口抛出异常,借助适配层统一转换。

示例代码

#include <iostream> #include <stdexcept> #include <optional> #include <system_error> // 异常方式 int divideException(int a, int b) { if (b == 0) throw std::runtime_error("除以零错误"); return a / b; } // 错误码方式 enum class ErrorCode { Ok, DivideByZero }; std::pair<ErrorCode,int> divideErrorCode(int a, int b) { if (b == 0) return {ErrorCode::DivideByZero, 0}; return {ErrorCode::Ok, a / b}; } int main() { // 异常处理 try { std::cout << "10 / 2 = " << divideException(10,2) << std::endl; auto res = divideException(10,0); std::cout << "10 / 0 = " << res << std::endl; } catch (const std::exception& e) { std::cout << "捕获异常: " << e.what() << std::endl; } // 错误码处理 auto [ec1, res1] = divideErrorCode(10,2); if (ec1 == ErrorCode::Ok) std::cout << "10 / 2 = " << res1 << std::endl; else std::cout << "错误码方式:除以零" << std::endl; auto [ec2, res2] = divideErrorCode(10,0); if (ec2 == ErrorCode::Ok) std::cout << "10 / 0 = " << res2 << std::endl; else std::cout << "错误码方式:除以零" << std::endl; return 0; }

运行结果:

10 / 2 = 5

捕获异常: 除以零错误

10 / 2 = 5

错误码方式:除以零

代码解读

divideException在除数为零时抛出std::runtime_error,由调用者在try-catch块中捕获并处理;

divideErrorCode返回一个(ErrorCode, int)对,让调用者显式检查ErrorCode并处理错误。

http://www.cnnetsun.cn/news/2998979.html

相关文章:

  • 手游 BGP 边缘分发部署实战:三网联机延迟优化与 UDP 异常流量过滤配置方案
  • 03. 从零带你学习Linux内核:proc
  • O-RAN中基于Transformer-ESN混合架构的KPI降维与预测优化
  • 基于Hadoop的番茄小说阅读量数据的分析与运用
  • AI开发可观测性实践:构建成本追踪与代码质量监控体系
  • 基于深度强化学习的多目标SAR无人机智能路径规划实战解析
  • OASIS框架:基于分层事件记忆的长视频流式理解技术解析
  • 基于视觉语言与扩散模型的自动驾驶场景生成技术解析
  • Trae:重构编程工作流的操作系统级AI开发工具
  • GitHub学生认证失败真相:不是打不开,而是信源不匹配
  • Codex本地技能调度器:解析.skill.md与配置原理
  • Claude API如何通过MCP协议接入VS Code与Playwright
  • OpenCode 部署指南:Node.js 环境配置与本地 AI 编程运行时搭建
  • C++标准库拷贝与替换算法原理及工程实践
  • 混元2.0深度实测:国产大模型结构化理解与工程稳定性解析
  • 多时序多视角输入加速:IRL输入规整层工程实践
  • Claude Ultracode Agent View:面向工程规模化AI开发的并行调度与可观测性实践
  • Burp Suite实战指南:从代理抓包到漏洞扫描的Web安全测试全流程
  • C语言独立加密库实现:MD5/SHA1/SHA256源码解析与工程实践
  • Java Selenium自动化测试框架搭建:从POM模式到数据驱动的工程实践
  • 微信链接被拦截?三步申诉指南与预防策略
  • 构建UI与API融合的自动化测试框架:工程实践与效能提升指南
  • Web自动化测试工具深度对比:Selenium、Cypress、Playwright与Puppeteer选型指南
  • KT0605无线话筒发射端Keil工程包,含C8051F310驱动、FM调制、LCD按键与I2C/SPI完整实现
  • DVWA文件上传High级绕过:图片马、GIF注释与竞争条件攻击实战
  • 文件格式伪装原理与Apate工具实战:从魔数识别到攻防对抗
  • CVE-2017-17733漏洞复现:从PHP eval()到远程命令执行实战
  • 制作5G新时代科学知识页面
  • 鸿蒙 Next 小众爱好图鉴 App 开发实战:兴趣发现 + 分类系统 + 收藏管理
  • MedPlanning影像规划助手最新中文版本