Будет ли выход (0) плохим в другом «пустом» блок?

Я пытался прочитать разницу между return EXIT_SUCCESS; от main() и звонит exit(EXIT_SUCCESS) из любого места, и лучший ресурс, который я нашел, этот ответ здесь на SO. Однако есть одна деталь, которую я хотел бы прояснить.

Для меня самый убедительный аргумент против exit() (как изложено в этом посте), что деструктор не вызывается на объектах локальной области действия. Но что это значит для Другой объекты? Что делать, если я звоню exit() откуда-то еще, довольно далеко от стека main() метод, но в блоке (даже метод), который содержит только этот вызов, и без переменных? Будут ли уничтожены объекты в другом месте в стеке?

Мой вариант использования такой:

У меня есть приложение, которое продолжает запрашивать ввод у пользователя, пока не будет дана команда «выйти» (текстовая приключенческая игра). Самый простой способ сделать это — сопоставить метод quit с методом, который просто вызывает exit(EXIT_SUCCESS), Конечно, я мог бы написать это так, чтобы каждый действие, которое пользователь может предпринять, возвращает логическое значение, указывающее, должна ли игра продолжаться или нет, а затем просто return false когда я хочу выйти — но только раз я бы вернул ничего, кроме true от этого метода — каждый другой метод действия должен был бы тогда return true только потому, что я хотел избежать exit(), С другой стороны, я создаю довольно много объектов и динамически выделяю достаточно памяти — обо всем этом должны заботиться деструкторы классов, поэтому очень важно, чтобы они выполнялись.

Какова лучшая практика здесь? Это хороший случай для exit()или так же плохо, как в main метод?

1

Решение

if (command == "quit") {
throw QuitGameException();
}

Вы могли бы бросить исключение. Исключение будет безопасно разматывать стек и уничтожать объекты во всех вызывающих по пути.

3

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

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

Я знаю одну причину использовать exit () — если вы в любом случае полностью обречены, и вы никак не можете выйти. В таком случае вы будете не выйти с кодом ноль. Итак, выход () с ненулевым значением, когда вы все равно собираетесь потерпеть крах.

В любой другой случай, создайте переменные, которые позволят вам покинуть основные циклы и выйти из main nice и sane, чтобы очистить всю вашу память. Если вы не напишите такой код, вы, например, никогда не сможет обнаружить все утечки памяти.

1

Будут ли уничтожены объекты в другом месте в стеке?

Нет, exit () делает следующее (по порядку):

  • Объекты, связанные с текущим потоком с продолжительностью хранения потока, уничтожаются (только C ++ 11).
  • Объекты со статической продолжительностью хранения уничтожаются (C ++) и вызываются функции, зарегистрированные с помощью atexit (если вызывается необработанное исключение, вызывается завершение).
  • Все потоки C (открытые с функциями в) закрываются (и сбрасываются, если буферизируются), и все файлы, созданные с помощью tmpfile, удаляются.
  • Управление возвращается в среду хоста

от: http://www.cplusplus.com/reference/cstdlib/exit/

exit () не разматывает стек, память для всего стека просто освобождается, деструктор для отдельных объектов в стеке не запускается. Использование exit () безопасно только тогда, когда все объекты, у которых нет простых деструкторов (тех, которые не имеют дело с внешними ресурсами), размещены в статическом хранилище (то есть глобальные переменные или статическая переменная локальной области действия). Большинство программ имеют обработчики файлов, соединения с сокетами, обработчики баз данных и т. Д., Которые могут выиграть от более плавного завершения работы. Обратите внимание, что динамически распределяемый объект (который не связан с внешними ресурсами) не обязательно должен быть освобожден, поскольку программа все равно собирается завершиться.

exit () — это функция, унаследованная от C, которая не имеет деструктора, поэтому очистка внешних ресурсов всегда может быть организована с помощью atexit (); в общем, очень трудно безопасно использовать exit () в C ++, вместо этого в C ++ вы должны написать свою программу в RAII и вызвать исключение для завершения и очистки.

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector