Использование бросков для управления потоком программ?

Программа общается с пользователем через class Menu, Итак main() выглядит так:

int main() {
try {
Menu menu(/*...*/);
while (true) {
menu.printOptions();
menu.chooseOption();
}
}
catch (const char *error) { /*Resolve error.*/ }
catch (int code) { /*Exit with code.*/ }
}

Текущий class MenuОпция, используемая для выхода, такова:

void exit() {
// Release memory.
throw 0;
}

Следует ли избегать подобных конструкций и есть ли у них непредсказуемые (или нежелательные) побочные эффекты?

0

Решение

Я бы не использовал исключения как средство управления потоком таким образом. Вместо этого вы можете изменить свой цикл, от while (true) к тому, что проверяет состояние класса меню, таких как while (menu.isAlive()), Для выхода нужно просто установить для атрибута alive значение false, что завершит цикл while.

Исключения следует использовать для ситуаций, из которых текущий поток не может восстановиться, и для этого требуется, чтобы вы вернули управление родительскому потоку. Сказав это, ничто не мешает вам использовать исключения таким образом, но Лично я считаю Достаточно плохо иметь исключения для обработки ошибок и, следовательно, скрытых переходов, но наличие их для регулярного управления потоком — это определенно то, что, я думаю, загрязнило код и сделало его менее предсказуемым.

Исключения имеют проблемы, которые вы также найдете во многих других статьях об анти-шаблонах:

  • Они во многом похожи на goto заявления о том, что они создают «невидимые» точки выхода в коде, что логический поток программы прерывается в точках, которые действительно могут усложнить пошаговое выполнение кода в обычном отладчике.
  • Дорого в использовании. Подробнее об этом ниже.
  • Делает код более сложным для чтения.
  • Является симптомом проблемы проектирования, которую следует устранить вместо этого.

Я не против исключений во всех ситуациях, но я не думаю, что вся обработка «ошибочных» ситуаций должна выполняться с использованием исключений, это зависит от того, как «ошибка» влияет на ход программы. Например, это имеет смысл в ситуациях, когда ошибка (извините за неверную формулировку) является действительно исключительным состоянием, например, когда умирает сокет, или вы не можете выделить новую память или что-то подобное. В этих случаях исключения имеют смысл, тем более что исключения трудно игнорировать. В итоге по-моему исключения должны использоваться для исключительных ситуаций.

На SO и других сайтах Stack Exchange можно найти другие ответы, которые могут вас заинтересовать:
Являются ли исключения в качестве контрольного потока серьезным антипаттерном? Если так, то почему?
Почему бы не использовать исключения в качестве регулярного потока управления?


Обратите внимание на производительность исключений, это зависит от реализации обработки исключений, и она может отличаться от компилятора к компилятору. Однако, часто исключения не добавляют дополнительных затрат при выборе неисключительного пути, однако при выборе исключительного пути есть ряд отчетов, которые предполагают, что стоимость действительно значительна (https://stackoverflow.com/a/13836329/111143 упоминает 10x / 20x стоимость обычного if на исключительном пути).

Поскольку реализации исключений являются специфическими для компилятора, может быть трудно дать какой-либо общий ответ на этот вопрос. Но изучение кода, сгенерированного компилятором, может показать, что добавляется при использовании исключений. Например, при перехвате исключений вам нужна информация о типе выданного исключения, что добавляет дополнительные затраты к выбрасыванию исключения. Эти дополнительные расходы не имеют большого значения, когда вы действительно сталкиваетесь с исключительным состоянием, которое случается редко. Но если он используется для контроля за регулярным потоком программ, это становится дорогостоящим делом.

Например, посмотрите на следующий пример простого кода, который завершается броском целого числа: https://godbolt.org/g/pssysL добавлена ​​глобальная переменная, чтобы компилятор не мог оптимизировать возвращаемое значение. Сравните это с простым примером, где используется возвращаемое значение: https://godbolt.org/g/jMZhT2 исключение имеет примерно такую ​​же стоимость, когда выбирается неисключительный путь, но становится дороже, если выбирается исключительный путь. Опять же, это может быть хорошо, если исключение используется для действительно исключительных ситуаций, но при использовании в ситуациях, когда «исключительный путь» встречается чаще, стоимость начинает становиться фактором.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]