我正在编写一个通用链表类,并在反向迭代器类中重载*运算符。这是我的:
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;
}
编辑:所以我认为我的第二个实现更好?但是,当我用第二个实现运行我的程序时,我仍然无法继续我的程序。我如何才能让它更安全,这样我的程序才能继续运行?
一旦进入catch块1,程序仍在运行。为了继续,您必须返回this->item->data
以外的内容。返回的内容取决于调用您的函数的意义。
IMHO,这是一个不好的异常用例。点击链接列表的末尾并不罕见,这是正常的,也是意料之中的事。大概你想抛出一个异常,这样当你到达列表的末尾时就不必对return this->item->data
进行特殊处理。但为了继续,你必须返回一些东西,然后你的调用者必须检查它。你只是把工作转移到另一个地方,并在这个过程中支付异常的费用。一个更好的解决方案是在最有意义的地方检查null。没有例外,没有额外费用。
catch (...)
对于这种情况来说太宽泛了。这抓住了一切。你真的应该试着把它限制在std::out_of_range
或它的祖先之一。否则,你会把你意想不到的东西集中到你的接球块里,你可能不会做好处理它们的准备
取消引用空指针是未定义的行为。(标准)从未指定它抛出异常。这就是您的第一个示例崩溃的原因。
如果这是你想要的行为,你的第二个例子是好的。标准的库行为是将无效的取消引用保持原样(未定义)。但如果你想实现一个更安全的替代方案,你可以自由选择
我如何才能让它更安全,这样我的程序才能继续运行?
您可以在任何级别使用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
。这样,您就不会从其他库中捕获您可能不准备处理的异常。