远程过程调用失败_C++核心指南(16) I.10 使用异常来表示执行所需任务的失败

a3590a5d029c80936634447320bb4bfe.png

I.10: 使用异常来表示执行所需任务的失败

原因

不应该忽略错误,因为这会使系统或计算处于未定义(或意外)的状态,这也是错误的主要来源。

示例

int printf(const char* ...); // 糟糕:当输出失败时返回负值template // 好的:当不能开始一个新线程时抛出system_errorexplicit thread(F&& f, Args&&... args);

Note

什么是错误?

一个错误意味着函数不能达到它所宣传的目的(包括建立后置条件),忽略错误的调用代码可能导致错误的结果或未定义的系统状态。例如,不能连接到远程服务器本身并不是一个错误:服务器可以出于各种原因拒绝连接,因此自然会返回调用者应该始终检查的结果;但是,如果连接失败被认为是错误,则失败应该引发异常。

例外

许多传统的接口函数(例如UNIX信号处理程序)使用错误代码(例如errno)来报告真正的状态,而不是错误。没有很好的替代方法来使用这样的函数,因此调用这些函数并不违反规则。

替代方法

如果您不能使用异常(例如,因为代码充满了旧式的raw指针使用,或者因为存在硬实时(hard-real-time)约束),请考虑使用返回一对值的方式:

int val;int error_code;tie(val, error_code) = do_something(); // 译注:tie是C++11的用法if (error_code) { // ... 处理错误或退出 ...}// ... 使用 val ...

不幸的是,这种风格导致了未初始化的变量(译注:int val;会导致val没有被初始化),处理这个问题的工具结构化绑定将在C++17中提供(译注:C++17已经支持)。

auto [val, error_code] = do_something();if (error_code) { // ... 处理错误或退出 ...}// ... 使用 val ...

Note

我们不认为“性能”是不使用异常的正当理由:

  • 通常,显式的错误检查和处理也会消耗与异常处理同样多的时间和空间。
  • 通常,干净的代码在有异常的情况下会产生更好的性能(简化和优化程序中路径的跟踪)。
  • 性能关键代码的一个好规则是将检查移到代码的关键部分之外(checking)。
  • 从长远来看,更规范的代码会得到更好的优化。
  • 在做出性能声明之前一定要仔细度量。

另请参阅: I.5 和 I.7 来报告违反先决条件和后置条件的情况

实施

  • (不可强制执行的) 这只是一个哲学意义上的指导,不具直接检查的可行性。
  • 寻找 errno。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值