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
- 在Windows 8 Hyper-V下的安装CentOS 6和SSH配置
- WordPress RSS Feed 优化/设置技巧六则
- SourceTree 基本介绍
- 学习Altas 笔记[JS简单调用服务端方法]
- 使用WinSCP软件在windows和Linux中进行文件传输
- 线程安全的Generic Dictionary
- Python 项目实践三(Web应用程序)第五篇
- CentOS 6.3下 安装 Mono 3.2 和Jexus 5.4
- Python 项目实践三(Web应用程序)第四篇
- 负载均衡环境下缓存处理
- WordPress Ajax 异步加载 自定义评论表情
- “分期网”域名fenqi.wang以16888元成交
- Python 项目实践三(Web应用程序) 第三篇
- Python 项目实践三(Web应用程序)第二篇
- 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 数组属性和方法
- Ubuntu18.04下安装MySQL(图文教程)
- 基于 ffmpeg+Webassembly 实现视频帧提取
- Ubuntu14.04 opencv2.4.8和opencv3.3.1多版本共存的实现方法
- 解决Unixbench安装报错信息的问题
- 关于安装LNMP集成包后上传图片报500错误的解决方法
- linux下SVN配置实现项目目录自动更新以及源码安装的操作方法
- linux安装redis和mysql的实例讲解
- tomcat服务器如何配置字符集为utf-8彻底解决中文乱码的问题详解
- Linux下Android开发环境搭建的操作方法
- liunx 时间函数与时间格式与字符串之间的转化方法
- 详解linux下的.net/mvc/cms程序结构
- Azure给ubuntu虚拟机挂载数据盘的详细步骤
- 详解SSH 远程执行任务的方法
- Linux基础学习之文件查找find的常见用法
- Linux基础之xargs命令的入门实例