C++核心准则E.2:通过抛出异常来表明函数无法执行指定的任务
E.2: Throw an exception to signal that a function can't perform its assigned task
E.2:通过抛出异常来表明函数无法执行指定的任务
Reason(原因)
To make error handling systematic, robust, and non-repetitive.
为了使用错误处理系统化,健壮和不繁琐。
Example(示例)
struct Foo {
vector<Thing> v;
File_handle f;
string s;
};
void use()
{
Foo bar {{Thing{1}, Thing{2}, Thing{monkey}}, {"my_file", "r"}, "Here we go!"};
// ...
}
Here, vector and strings constructors may not be able to allocate sufficient memory for their elements, vectors constructor may not be able copy the Things in its initializer list, and File_handle may not be able to open the required file. In each case, they throw an exception for use()'s caller to handle. If use() could handle the failure to construct bar it can take control using try/catch. In either case, Foo's constructor correctly destroys constructed members before passing control to whatever tried to create a Foo. Note that there is no return value that could contain an error code.
这里vector和string的构造函数可能无法为它们的元素分配足够的内存,vector构造函数可能无法复制初始化列表中的内容,File_handle有可能无法打开需要的文件。每种情况中,它们都会向调用者抛出异常以便处理。如果use()可以处理构造bar对象时的错误,它们可以通过try/catry获得控制。其他情况下,Foo的构造函数可以在将控制权交给试图构建Foo的代码之前正确地销毁已经构造完成的成员。注意,代码中没有可以容纳错误码的返回值。
The File_handle constructor might be defined like this:
File_handle的构造函数可能被定义成下面的样子:
File_handle::File_handle(const string& name, const string& mode)
: f{fopen(name.c_str(), mode.c_str())}
{
if (!f)
throw runtime_error{"File_handle: could not open " + name + " as " + mode};
}
Note(注意)
It is often said that exceptions are meant to signal exceptional events and failures. However, that's a bit circular because "what is exceptional?" Examples:
一般情况下会认为异常意味着重大的例外事件和错误。然而,这个问题多少有点绕,到底什么是例外?例如:
- A precondition that cannot be met
- 一个前提条件没有满足
- A constructor that cannot construct an object (failure to establish its class's invariant)
- 构造函数无法构造对象(无法建立类的不变式)
- An out-of-range error (e.g., v[v.size()] = 7)
- 越界错误(例如 v[v.size()]=7)
- Inability to acquire a resource (e.g., the network is down)
- 无法获取资源(例如:网络断)
In contrast, termination of an ordinary loop is not exceptional. Unless the loop was meant to be infinite, termination is normal and expected.
相反,结束一个通常的循环不属于异常。只要它不是无限循环,中止就是正常和期待的。
Note(注意)
Don't use a throw as simply an alternative way of returning a value from a function.
不要使用将抛出异常作为从函数中返回结果的另一种方式使用。
Exception(例外)
Some systems, such as hard-real-time systems require a guarantee that an action is taken in a (typically short) constant maximum time known before execution starts. Such systems can use exceptions only if there is tool support for accurately predicting the maximum time to recover from a throw.
有些系统,例如硬实时系统要求保证一个动作在开始执行之前就能确定其执行时间小于某个固定值(通常很小)。这样的系统只有在存在某种可以准确预测系统从抛出异常过程中恢复的最大时间的工具时才可以使用异常。
See also: RAII
参见:
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#e6-use-raii-to-prevent-leaks
See also: discussion
参见:
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#discussion-usage-of-noexcept
Note(注意)
Before deciding that you cannot afford or don't like exception-based error handling, have a look at the alternatives; they have their own complexities and problems. Also, as far as possible, measure before making claims about efficiency.
在决定你无法承担或者不喜欢基于例外的错误处理之前,考虑以下其他选项;它们包含自己的复杂性和问题。同时,只要可能的话,在抱怨效率问题之前进行测量。
原文链接https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#e2-throw-an-exception-to-signal-that-a-function-cant-perform-its-assigned-task
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- SAP S/4HANA Customer Management(CRM)模块的扩展性设计
- SAP S/4HANA Customer Management(CRM)模块的Partner模型设计
- 使用soapUI消费SAP Cloud for Customer的web service
- 视频上云网关EasyNTS智能云组网如何通过23端口穿透实现远程控制功能?
- 视频上云网关平台EasyCVR登录页开发控制台报net::ERR_CONNECTION_TIMED_OUT错误
- 视频监控系统视频上云解决方案EasyCVR集成海康EHome私有协议系列——开启存储服务
- 设计模式~责任链模式
- 大数据计算的基石——MapReduce
- SPA单页应用的优缺点
- 《JavaScript 模式》读书笔记(7)— 设计模式1
- CenterNet测试推理过程
- Docker学习笔记[nginx]
- MySQL集群搭建方案(PXC)
- Java8——行为参数化传递代码
- 【设计模式系列(二)】彻底搞懂单例模式