c – 异常安全 – 何时,如何,为什么?

前端之家收集整理的这篇文章主要介绍了c – 异常安全 – 何时,如何,为什么?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我只是一个刚刚起步的程序员,至少尝试编程比最好的情况.我一直在阅读Herb Sutter的“超凡C”,并且到目前为止,经过了例外安全专栏三次.然而,除了他提出的例子(一个Stack),我真的不知道我究竟应该为异常安全与速度争取什么,而且只是这么简单的愚蠢.

例如,我目前的家庭作业项目是双向列表.既然我已经编写了几个这样的内容,我想花点时间来深入了解一些更深层的概念,如ES.

这是我的弹出式功能

void List::pop_front()
{
    if(!head_)
        throw std::length_error("Pop front:  List is empty.\n");
    else
    {
        ListElem *temp = head_;
        head_          = head_->next;
        head_->prev    = 0;
        delete temp;
        --size_;
    }
}

我有这样的困境.

1)列表出现故障时是否应该抛出错误?我不应该简单地做任何事情,而不是强制列表的用户执行try {] catch(){}语句(也很慢).

2)有多个错误类(加上我的老师要求我们在课堂上实现的ListException).是一个自定义错误类对于这样的事情真的有必要,并且有什么时候使用特定的异常类的一般指导? (例如,范围,长度和边界都是一样的)

3)我知道我不应该改变程序状态,直到抛出异常的所有代码才能完成.这就是为什么我减少size_最后.这个简单的例子真的有必要吗?我知道删除不能抛出.当分配到0时,头_->上一次可能会发生吗? (头是第一个节点)

我的push_back函数

void List::push_back(const T& data)
{
    if(!tail_)
    {
        tail_ = new ListElem(data,0);
        head_ = tail_;
    }
    else
    {
    tail_->next = new ListElem(data,tail_);
    tail_ = tail_->next;
    }
    ++size_;
}

1)我经常听到C程序中的任何事情都会失败.测试ListElem的构造函数是否失败(或在新建期间tail_)是否现实?

2)是否有必要测试数据类型(目前是一个简单的typedef int T,直到我模拟所有内容),以确保该类型对于结构是可行的?

我意识到这些都是过于简单的例子,但是目前我只是很困惑,当时我应该练习好ES,而不是.

解决方法

Should I really throw an error when a list fails? Shouldn’t I rather simply do nothing and return instead of forcing the user of the list to perform try {] catch() {} statements (that are also slow).

绝对抛出异常.

用户必须知道如果列表为空,会发生什么 – 否则将会被调试.用户不被强制使用try / catch语句;如果异常是意外的(即只能由于程序员的错误而发生),则没有理由试图抓住它.当一个异常没有被捕获时,它直到std :: terminate,这是非常有用的行为.无论如何,try / catch语句本身也不慢;实际抛出的异常和堆叠的费用是多少.如果没有抛出异常,它几乎没有任何东西.

There are multiple error classes (plus the ListException my teacher demands we implement in the class). Is a custom error class really necessary for such a thing,and is there a general guide on when to use a specific exception class? (For example,range,length and boundary all sound alike)

尽可能具体.使用自己的错误类是最好的方法.使用继承来分组相关的异常(使得调用者可以更容易地捕获它们).

I know I shouldn’t change the program state until all that code that has thrown an exception be done. This is why I’m decrementing size_ last. Is this really necessary in this simple example? I know delete can’t throw. Is it possible for head_->prev to ever throw when assigning to 0? (head is the first Node)

如果head_为null,则解除引用(作为尝试分配给头_-> prev的一部分)是未定义的行为.抛出一个例外是未定义行为的可能后果,但不太可能的一个行为(它需要编译器不得不把握住你的手,用一种这样的东西被认为是荒谬的语言)),而不是一个我们担心,因为未定义的行为是未定义的行为 – 这意味着你的程序已经错了,无论如何,错误的方式更合适.

此外,您已经明确检查head_不是null.所以没有问题,假设你没有做任何事情的线程.

I hear often that anything can fail in a C++ program.

这是稍微偏执.

猜你在找的C&C++相关文章