我一直在寻找这个问题的答案:
Program doesn't stop after exception
被接受的作者提出了各种技术来在捕获异常时退出程序,但也要注意
退出和中止将不会调用本地对象的析构函数。
因此,如果我使用第一个建议(即使用return关键字),我怎么知道要返回什么?
例如,我正在编写一个Stack<T>
类,并实现了Pop函数,如下所示:
template <typename T>
T Stack<T>::Pop() {
try {
return m_stack[--m_current_index];
} catch(OutOfBoundsException &obe) {
std::cout << "Stack Underflow" << std::endl;
}
}
在这里,m_stack
是类型为Array<T>
的自定义数组对象,它引发一个OutOfBoundsException
。
Stack<T>
遵循非常基本的实现策略,其中m_current_index
表示堆栈的顶部,堆栈大小是固定的。因此,任何推入和弹出操作都只会使m_current_index
递增或递减。
假设我的堆栈实例化为Stack<int> int_stack;
,并且弹出了我堆栈中的所有值。现在,当我调用Pop函数(int_stack.Pop()
)时,将得到以下输出。
堆栈下溢
5
5是数组索引0处的值。
现在,如果我在捕获到异常时使用return关键字退出程序,我真的不能只返回整数,因为尽管有异常,但用户可能会认为它是整数堆栈上的有效值。
答案 0 :(得分:3)
因此,如果我使用第一个建议(即使用return关键字),我怎么知道要返回什么?
这里有两个问题。
如果第一个问题的答案为“是”,则第二个问题相关。如果第一个问题的答案是“否”,则第二个问题不相关。
就您而言,我认为第一个问题的答案是“否”。如果要调用本地对象的析构函数,则最好的选择是在std::cout
行之后抛出异常。
template <typename T>
T Stack<T>::Pop() {
try {
return m_stack[--m_current_index];
} catch(OutOfBoundsException &obe) {
std::cout << "Stack Underflow" << std::endl;
throw; // Throw the same exception
}
}