|
2 / 2 / 0
Регистрация: 16.08.2013
Сообщений: 86
|
||||||
Как избежать использования разрушенной переменной?16.11.2023, 02:12. Показов 2510. Ответов 27
Метки нет (Все метки)
Никак не могу найти приемлимое решение следующей проблемы.
Допустим, мы имеем логирующую функцию log(), которая может быть вызвана из любого места программы. Например:
Вижу следующие варианты, которые мне не совсем нравятся: * Не создавать в деструкторах зависимость от других глобальных переменных. В данном примере - не вызывать log() из ~A(). Но ведь можно представить ситуацию, что в деструкторе ожидается завершение параллельного потока, который как раз может использовать log()... * Переместить в самый верх кода подобные глобальные переменные, делая их последними в очереди на разрушение. В данном примере - переместить "m" наверх. Но тогда реализация функции log() будет разделена на 2 части...
0
|
||||||
| 16.11.2023, 02:12 | |
|
Ответы с готовыми решениями:
27
Как избежать использования оператора goto? Как избежать использования кучи проверок? Как избежать утечки памяти: нюансы использования QList |
|
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
|
||||||||||||||||||||||
| 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 | |
|
Помогаю со студенческими работами здесь
28
Как избежать глобальной переменной
Как получить счетчик использования переменной? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
||||
|
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
|
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение.
И на уровне агентов добавится между грибами или бактериями взаимодействий.
До того я пробовал подход через многомерные массивы,. . .
|
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Programma_Boinc 01.01.2026
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Сочетание глобально распределённой вычислительной мощности и инновационных. . .
|
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Налог на собак: https:/ / **********/ gallery/ V06K53e
Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf
Пост отсюда. . .
|
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop?
Ниже её машинный перевод.
После долгих разбирательств я наконец-то вернула себе. . .
|
|
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод
Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод.
Thinkpad X220 Tablet —. . .
|
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта
Симптом:
После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
|
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
|
Новый ноутбук
volvo 07.12.2025
Всем привет.
По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне:
Ryzen 5 7533HS
64 Gb DDR5
1Tb NVMe
16" Full HD Display
Win11 Pro
|
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
|