|
2 / 2 / 0
Регистрация: 16.08.2013
Сообщений: 86
|
||||||
Как избежать использования разрушенной переменной?16.11.2023, 02:12. Показов 2767. Ответов 27
Метки нет (Все метки)
Никак не могу найти приемлимое решение следующей проблемы.
Допустим, мы имеем логирующую функцию log(), которая может быть вызвана из любого места программы. Например:
Вижу следующие варианты, которые мне не совсем нравятся: * Не создавать в деструкторах зависимость от других глобальных переменных. В данном примере - не вызывать log() из ~A(). Но ведь можно представить ситуацию, что в деструкторе ожидается завершение параллельного потока, который как раз может использовать log()... * Переместить в самый верх кода подобные глобальные переменные, делая их последними в очереди на разрушение. В данном примере - переместить "m" наверх. Но тогда реализация функции log() будет разделена на 2 части...
0
|
||||||
| 16.11.2023, 02:12 | |
|
Ответы с готовыми решениями:
27
Как избежать использования оператора goto? Как избежать использования кучи проверок? Как избежать утечки памяти: нюансы использования QList |
|
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
|
||||||||||||||||||||||
| 17.11.2023, 13:08 | ||||||||||||||||||||||
|
Есть такая палочка-выручалочка, которая позволяет разруливать самые разные грабли, связанные с единицами трансляции: 1. Нужно приготовить правильный предварительно скомпилированный заголовок. Правильный - это когда вам не нужно вручную писать всякую вредительскую дрянь наподобие #include "stdafx.h"Все современные компиляторы имеют опции, с помощью которых можно задать автоматическое подключение предварительно скомпилированного заголовка к каждой ед. трансляции. 2. В предваритально скомпилированном заголовке, первой же строкой подключаем хедер, с таким содержимым:
state, приводит к запуску функции glob::initialize(), которая в свою очередь инициализирует локальный статический объект класса initial, который в свою очередь организует обращение к глобальным точкам доступа, которые в свою очередь приводят к их инициализации.В итоге получаем инициализацию всех глобальных точек доступа в нужной последовательности. Таким образом, предварительно скомпилированный заголовок гарантирует заданный порядок инициализации глобальных точек доступа ещё до начала main, а так же, до начала динамической инициализации глобальных переменных, описанных в файлах.cpp Единственное слабое место: глобальные точки доступа не должны ссылаться друг на друга. Если у вас есть два статических объекта: A и B, и при этом они ссылаются друг на друга в конструкторе, тогда произойдет зацикливание при инициализации. А в самих ед. трансляции уже даже заголовки всяких логгеров подключать не нужно. Можно сразу использовать:
1
|
||||||||||||||||||||||
|
2 / 2 / 0
Регистрация: 16.08.2013
Сообщений: 86
|
|
| 17.11.2023, 13:33 [ТС] | |
|
eva2326, вот за это огромное спасибо!
0
|
|
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|
| 17.11.2023, 14:06 | |
|
Paket236,
Можно сделать проще. 1) Создать класс Logger 2) Создать экземпляр Logger через std::shared_ptr 3) Передавать std::shared_ptr<Logger> туда где нужно логировать Далее в деструкторе можно свободно логировать, так как механизм подсчета ссылок будет гарантировать сохранность объекта.
0
|
|
|
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
|
|
| 17.11.2023, 14:12 | |
|
Undisputed, где и как создать-то?
0
|
|
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|||||||
| 17.11.2023, 15:05 | |||||||
1) проще потому что время жизни объекта гарантируется std::shared_ptr вместо того что бы полагаться на порядок разрушения объектов, который требует аккуратного создания объектов в строго определенном порядке а так же знание соответствующих деталей языка (даже безобидная перестановка вызовов может привести к тому что все поломается... а как насчет надежности решения?). Это так же усложняет поддержку, так как многие знают что такое std::shared_ptr, а вот эти order-ы создания и уничтожения объектов сходу не каждый помнит/поймет что на них и полагается автор кода. 2) более гибкое как минимум потому, что при передачи логгера как аргумента, появляется возможность использовать разного типа логгеры (можно передавать как аргумент file_logger, console_logger, databse_logger и так далее) а не зависеть только от одного способа логирования В итоге получаем более гибкое, и более простое для понимания решение. В общем если ТС нужно более надежное, простое и гибкое решение, рекомендую забросить текущую идею и принять во внимание этот пост.
0
|
|||||||
|
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
|
|
| 17.11.2023, 16:19 | |
|
Undisputed, тогда a, b придётся передавать как параметры везде, где они нужны.
0
|
|
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
||
| 17.11.2023, 16:43 | ||
По возможности желательно зависимости передавать через аргументы, это более гибко, так как это позволяет передавать функции разные аргументы, и не завязывать функцию на один конкретный объект.Но если очень хочется глобальности, то выход есть. Можно в глобальном неймспейсе создать std::unique_ptr<A>, затем reset-нуть его создав реальный объект (например, в main), и при создании объекта через reset передать ему логгер, и таким образом не нужно будет передавать A и B как аргумент везде... Но в целом лучше конечно же через аргументы как минимум исходя из вышеупомянутых соображений. На самом деле разные варианты есть, как получить желаемое. Например, можно создать класс app, и что бы выполнение программы начиналось с его метода run и путь app хранит необходимые "глобальные" объекты в качестве полей. Пока не завершится run, все объекты будут в строю.
1
|
||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
||||||
| 18.11.2023, 11:53 | ||||||
|
Вот пример решения через класс app
1
|
||||||
| 18.11.2023, 11:53 | |
|
Как избежать глобальной переменной
Как получить счетчик использования переменной? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version
Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
|
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер
На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
|
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/
TL DR
Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
|
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык.
Возвращает он вот это:
https:/ / i. **********/ vqBWLe2. png
Нужную строчку в 3й колонке просто выдумал. .
Это. . .
|
|
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor.
Это. . .
|
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js.
В помощники взял Яндекс-Алису.
Было создано три зала на разные интересы.
исторические и ретро
сериал Хичкок. . .
|
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
|
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#.
Название изменил на ColorStep.
Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
|