如何处理异常,以便我的程序仍然运行?

时间:2012-12-10 17:13:31

标签: c++ exception c++11 exception-handling

我正在编写一个通用的链表类,我在我的反向迭代器类中重载了*运算符。这就是我所拥有的:

try
{
    return this->item->data;
}
catch (...)
{
    cout << "OUT OF RANGEEEEE" << endl;
}   

item,这是我的链表类的节点,可能是nullptr,因为我的指针指向rend()位置。在这种情况下,我怎么能处理该异常,以便我的程序仍然运行?我尝试使用此代码运行,但我的程序崩溃了。

另外,做这样的事情会没事吗?

if (item == nullptr)
{
    throw std::out_of_range("Error message here!");
}
else
{
    return this->item->data;
}

编辑: 所以我认为我的第二次实施更好?但是,当我用第二个实现运行我的程序时,我无法继续我的程序。我怎样才能让它更安全,所以我的程序会继续运行?

2 个答案:

答案 0 :(得分:3)

一旦进入catch块 1 ,您的程序仍在运行。要继续,您必须返回this->item->data以外的内容。你返回的内容取决于对你的功能有何意义。

恕我直言,这是一个异常的坏用例。点击链接列表的末尾并不例外,这是正常的和预期的。大概你想要抛出异常,这样当你点击列表的末尾时就没有特殊情况return this->item->data了。但是为了继续,你必须返回某些东西然后你的调用者必须检查它。你只是将这项工作转移到另一个地方,并且支付异常费用。一个更好的解决方案是在最有意义和完成的地方检查null。没有例外,没有额外费用。


  1. catch (...)对于这种情况来说太宽泛了。这抓住了一切。您应该尝试将其限制为std::out_of_range或其祖先之一。否则你得到的东西你并没有被期待集中到你的捕获块中,你可能不会准备好处理它们。

答案 1 :(得分:2)

取消引用空指针是未定义的行为。从未指定(通过标准)抛出异常。这就是你的第一个例子崩溃的原因。

你的第二个例子是好的,如果这是你想要的行为。标准库行为只是保留无效的解引用(未定义)。但是如果你想实现更安全的替代方案,你可以自由地这样做。

  

如何让它更安全,我的程序将继续运行?

您可以在任何级别使用try-catch块。例如:

try {
    MyListType<int> my_list;
    // do a bunch of stuff here involving my_list::iterators
    // If one is improperly dereferenced, an `std::out_of_range`
    // exception will be thrown, and caught below
} catch (std::out_of_range & e) {
    // your error handling
}

我建议你制作自己特定类型的例外,可能来自std::out_of_range。这样你就不会捕获其他你可能不准备处理的库的异常。