Явное уничтожение статического объекта без указателя

#c #static #destructor

#c #статический #деструктор

Вопрос:

Я работаю с Autodesk Maya api и MLibrary::cleanup функцией «…предотвращает выполнение любых статических деструкторов.»источник

Код, использующий Maya api, также использует некоторые из моих DLL-файлов, которые содержат статические переменные без указателя, которые необходимо уничтожить (в частности, класс Log, который содержит static Log stdLog , которому необходимо записать нижний колонтитул и закрыть файловый поток).

Каков подходящий способ справиться с этим? Я добавил Log::destroy() функцию, которая вызывает stdLog.~Log(); , безопасно ли это?

Ответ №1:

Может быть, это безопасно, может быть, нет. Лучше структурировать код так, чтобы это не имело значения. Вместо того, чтобы иметь destroy call ~Log , есть ~Log call destroy . Также destroy проверьте, не уничтожен ли уже объект; добавьте логическую переменную, чтобы отслеживать это, если необходимо.

Ответ №2:

Я бы переместил статические объекты в объекты кучи и добавил бы вызов, разрешающий чистое завершение работы. Если вы явно вызываете деструктор для нединамического объекта, то в случае обычного завершения программы деструктор будет вызван дважды, и это IMO плохо.

Использование явного вызова shutdown может корректно обрабатывать оба случая (т. Е. обычное завершение без завершения работы и обычное завершение после явного завершения работы).

Кстати, по моему опыту, наличие «сложных» статических экземпляров вообще является проблемой, потому что вы не можете точно контролировать, когда они создаются и когда они уничтожаются. Если построение или уничтожение может по какой-либо причине завершиться неудачей, то наверняка использование этих объектов в качестве экземпляров статической длительности означает, что вы ищете проблемы.

Также, по моему опыту, отладка проблем, которые возникают до выполнения первой инструкции main или после ее возврата, еще сложнее, чем обычная отладка (например, ошибка segfault, которая происходит во время завершения работы программы в Windows, довольно часто отключается ОС, и отладка перед запуском main может работать не так, как ожидалось).

За эти годы я перешел от ленивой инициализации / уничтожения к контролируемому детерминированному подходу к запуску / выключению (если это возможно) и не оглядываюсь назад.

Ответ №3:

Если ваш деструктор stdLog действительно никогда не вызывался, то да, это безопасно.

Ответ №4:

Вы могли бы заставить свои объекты «Static Storage Duration» регистрировать atexit() или on_exit() методы очистки как часть построения и ничего не делать во время уничтожения.

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