我正在查看这个问题的答案: 程序在异常
后不会停止
被接受的作者提出了各种技术,以便在捕获异常时退出程序,但也指出
退出和中止不会调用本地对象的析构函数。
那么,如果我使用第一个建议,即使用 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 关键字在捕获异常时退出程序,我实际上不能只返回一个整数,因为尽管收到异常,用户可能会认为它是整数堆栈上的有效值。
那么,如果我使用第一个建议,即使用 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
}
}