Как выйти из выполнения программы после отлова исключения - PullRequest
0 голосов
/ 28 августа 2018

Я искал ответ на этот вопрос: Программа не останавливается после исключения

Принятый автор предлагает различные методы выхода из программы при обнаружении исключения, но также отмечает, что

exit и abort НЕ будут вызывать деструкторы ваших локальных объектов.

Итак, если я воспользуюсь первым предложением, которое заключается в использовании ключевого слова 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 представляет вершину стека, а размер стека фиксирован. Поэтому любые операции push и pop просто увеличивают или уменьшают m_current_index.

Предположим, что мой стек создан как Stack<int> int_stack;, и я вытолкнул все значения из моего стека. Теперь, когда я вызываю функцию Pop (int_stack.Pop()), я получаю следующий вывод.

Стека стека
5

5 - это значение индекса 0 массива.

Теперь, если я использую ключевое слово return для выхода из программы после перехвата исключения, я не могу просто вернуть целое число, потому что пользователь может подумать, что это допустимое значение в стеке целых чисел, несмотря на получение исключения.

1 Ответ

0 голосов
/ 28 августа 2018

Итак, если я воспользуюсь первым предложением, которое заключается в использовании ключевого слова return, как мне узнать, что вернуть?

Здесь есть две проблемы.

  1. Уместно ли вообще что-либо возвращать?
  2. Какое значение вернуть?

Если ответ на первый вопрос «Да», то второй вопрос имеет значение. Если ответ на первый вопрос «Нет», то второй вопрос не имеет значения.

В вашем случае я бы сказал, что ответ на первый вопрос - «Нет». Если вы хотите, чтобы вызывались деструкторы локальных объектов, лучше всего выбросить исключение после строки 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
    }
}
...