1

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

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;
}

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

4

2 回答 2

3

一旦您进入 catch 块1 ,您的程序仍在运行。为了继续,您必须返回this->item->data. 您返回的内容取决于调用您的函数的意义。

恕我直言,这是一个糟糕的例外用例。命中链表的末尾并不例外,这是正常的和意料之中的。return this->item->data大概你想抛出一个异常,所以当你到达列表末尾时你不必特殊情况。但是为了继续,你必须返回一些东西,然后你的调用者必须检查它。您只是将这项工作转移到另一个地方并在此过程中支付异常的成本。更好的解决方案是在最有意义的地方检查 null 并完成。没有例外,没有额外费用。


  1. catch (...)对于这种情况来说太宽泛了。这抓住了一切。您真的应该尝试将其限制为std::out_of_range或其祖先之一。否则,您会将未预料到的东西集中到您的 catch 块中,并且您可能不会准备好处理它们。
于 2012-12-10T17:26:32.107 回答
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. 这样,您就不会从其他库中捕获您可能不准备处理的异常。

于 2012-12-10T17:24:06.740 回答