专栏首页C++核心准则原文翻译C++核心准则E.2:通过抛出异常来表明函数无法执行指定的任务

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

本文分享自微信公众号 - 面向对象思考(OOThinkingDalian),作者:面向对象思考

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-07-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • C++核心准则编译边学-F.26 使用unique_ptr<T>代替指针传递所有权

    Using unique_ptr is the cheapest way to pass a pointer safely.

    面向对象思考
  • C++核心准则Enum.6:避免无名枚举

    If you can't name an enumeration, the values are not related

    面向对象思考
  • C++核心准则编译边学-F.21 如果需要返回多个输出值,最好返回结构体或者tuple

    A return value is self-documenting as an "output-only" value. Note that C++ does...

    面向对象思考
  • SAP 委外工序带料外协

    在最近的工作中,有业务同事在对生产订单进行261投料时,报错:具有移动类型543的货物移动不可能,如下:

    用户5495712
  • 使用strptime函数时遇到的一个坑

    做新专辑排序的需求时,需要对专辑的时间进行排序,由于目前该字段是字符串类型的日期,在排序函数中要转成标准的UNIX时间戳来进行对比,大概代码如下:

    jackieluo
  • 李飞飞、邓中翰入选美国工程院院士,多位华人上榜

    当选美国国家工程院院士是工程领域专家的最高专业荣誉之一,以表彰入选者「在工程研究、实践、教育等方面做出的重大贡献」,「在新兴领域技术做出的开拓性工作和传统工程领...

    机器之心
  • 高并发下收藏功能设计

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    DencyCheng
  • DC-2靶机渗透实操全过程,一起来玩吧!

    这次的靶机渗透实战是一个找寻靶机中的flag的过程,并以获得最终的flag为目标。靶机下载地址:http://www.five86.com/dc-2.html

    轩辕小子
  • 动态规划初步

    动态规划是将大问题转化为小问题,然后一步步求解出最终结果。具体到这道题,我们可以把大问题即凑amount元转化为凑齐amout-1,amount-2等等

    racaljk
  • 苹果收购里“谷歌系”AI创业公司,更懂你的Siri要来了

    苹果再次出手收购AI公司了,公司目前已经确认,完成了对硅谷小型机器学习创业公司Laserlike的收购,但未透露购买原因和收购金额。

    量子位

扫码关注云+社区

领取腾讯云代金券