Да, exit(0)
- лучшее решение.Это приведет к запуску деструкторов глобальных объектов (и static
объектов внутри функций), однако не приведет к запуску деструкторов объектов, выделенных в стеке или в куче:
// At global scope
ClassWithDestruct globalObject;
void SomeFunction()
{
static ClassWithDestructor staticObject;
ClassWithDestructor stackObject;
ClassWithDestructor *heapObject = new ClassWithDestructor;
// On the following call to exit(), the destructors of 'globalObject' and
// 'staticObject' will run, but those of 'stackObject' and 'heapObject' will
// NOT run
exit(0);
}
или нет, это потокобезопасно, на этот вопрос сложно ответить: вам не следует одновременно звонить по номеру exit
из нескольких потоков, вы должны вызывать его только один раз.Если какие-либо деструкторы запускаются в результате выполнения exit
или любой другой функции, зарегистрированной в atexit
, то очевидно, что эти функции должны быть поточно-ориентированными, если имеют дело с данными, которые потенциально могут быть использованыдругими потоками.
Если ваша программа выходит нормально (скажем, в результате запроса пользователя на выход), вам следует либо вызвать exit
, либо вернуться из main
/ WinMain
, чтоэквивалентно звонку exit
.Если ваша программа завершает работу ненормально (скажем, в результате нарушения доступа или неудачного подтверждения), вам следует позвонить либо _exit
, либо abort
, что не вызывает деструкторов.