Как только я закрываю приложение, вызывается деструктор объекта этого класса (одиночка), и в деструкторе я использую эти переменные, но они на тот момент являются пустыми строками. Насчет того, что они явно нигде не обнуляются, я уверен полностью, но факт остается фактом — я не могу их использовать и все плохо
Здравствуйте, R1K0, Вы писали:
RK>Подскажите ПЛЗ где я не прав и что делаю не так.
Скорее всего очередной обычный фейл, связанный с тем, что порядок деинициализации статических объектов не определён. Объект класса, который уничтожается деструктором, вполне может быть уничтожен после отработки деструкторов статических членов класса, при выходе из приложения. Как с раскруткой стека повезёт. Вам вот не повезло...
В общем: не полагайтесь в деструкторе на то, что статические члены ещё живы.
RK>Как только я закрываю приложение, вызывается деструктор объекта этого класса (одиночка), и в деструкторе я использую эти переменные, но они на тот момент являются пустыми строками. Насчет того, что они явно нигде не обнуляются, я уверен полностью, но факт остается фактом — я не могу их использовать и все плохо
RK>Подскажите ПЛЗ где я не прав и что делаю не так.
А для чего ты насоздавал такое количество открытых статических переменных?, У тебя же сам класс CacheSystem реализован как Sigleton, вот и сделай эти переменные закрытыми нестатическими членами этого класса. А для доступа к этим строкам заведи в классе методы, нестатические опять же.
Даже при реализации паттерна Singleton знание о том, что данный объет должен быть единственным, нужно стараться локализовать как можно сильнее. В идеале, если это возможно, реализация функций-членов класса вообще не должна полагаться на то, что данный объект будет синглтоном. И только один единственный метод класса реализует его как одиночку. А еще лучше стратегию владения объектом-одиночкой сделать внешней по отношению к классу, реализующему основную его функциональность. При таком подходе проблем с рефакторингом будет меньше и вероятность повторного использования кода возрастает.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, Tilir, Вы писали:
T>Здравствуйте, R1K0, Вы писали:
RK>>Подскажите ПЛЗ где я не прав и что делаю не так.
T>Скорее всего очередной обычный фейл, связанный с тем, что порядок деинициализации статических объектов не определён. Объект класса, который уничтожается деструктором, вполне может быть уничтожен после отработки деструкторов статических членов класса, при выходе из приложения. Как с раскруткой стека повезёт. Вам вот не повезло...
T>В общем: не полагайтесь в деструкторе на то, что статические члены ещё живы.
Как вариант — можно явно запускать уничтожение этого синглтона до выхода из мейна.
Здравствуйте, Nik_1, Вы писали:
T>>В общем: не полагайтесь в деструкторе на то, что статические члены ещё живы.
N_>Как вариант — можно явно запускать уничтожение этого синглтона до выхода из мейна.
Можно. Пока кто-нибудь не сделает exit() откуда-нибудь из середины приложения и всё снова рухнет. Если приложение WinAPI, то оно обычно так и завершится -- по закрытию окна. Или консольное -- по закрытию консоли крестиком задолго до выхода из main(). В принципе можно такие вещи конечно руками отслеживать... но в общем случае лучше без нужды вообще не рисковать.
Здравствуйте, Tilir, Вы писали: T>Можно. Пока кто-нибудь не сделает exit() откуда-нибудь из середины приложения и всё снова рухнет.
За такое следует отрезать яйца, чтоб разработчики, делающий вызов exit() в модуле который ни коим боком не отвечает за время жизни приложения(а также его загрузку и выгрузку), не оставляли после себя потомство умственных инвалидов. T>Если приложение WinAPI, то оно обычно так и завершится -- по закрытию окна.
Ничего подобного, в этом случаи всеголишь шлется сообщение WM_CLOSE. А нормальные разработчики если хотят при закрытии именно этого окна завершать приложение, то в обработчики сообщения WM_DESTROY этого окна вызывают PostQuiteMessage, которая в свою очередь выставит флаг что очереди обработки сообщений нужно завершиться. Соответственно после выхода из цыкла обработки сообщений приложение выполнит все необходимый действия для корректоного завершения и вернет управление из фанкции мейн. T>Или консольное -- по закрытию консоли крестиком задолго до выхода из main(). В принципе можно такие вещи конечно руками отслеживать... но в общем случае лучше без нужды вообще не рисковать.
Консольное приложение — это отдельный и довольно извратский способ. Пользователь "сам дурак" если выходит из него по крестику, а не штатными методами.
Здравствуйте, Nik_1, Вы писали:
T>>Или консольное -- по закрытию консоли крестиком задолго до выхода из main(). В принципе можно такие вещи конечно руками отслеживать... но в общем случае лучше без нужды вообще не рисковать. N_>Консольное приложение — это отдельный и довольно извратский способ. Пользователь "сам дурак" если выходит из него по крестику, а не штатными методами.
Почему это сам дурак?
Крестик приводит к signal(SIGINT), то же самое будет, если пользователь нажмёт Ctrl+Break (или Ctrl+C). Вполне себе штатное действие.
Если программа с претензиями на интерактивность, то она должна в обработчике сигнала взвести флажок, а в ходе основной работы этот флажок опрашивать, и как можно скорее выходить удобным безопасным способом.
Хотя в некоторых случаях безопасен будет и exit() прямо из обработчика сигнала.
Например, если программа записывает структурированные файлы, то транзакционность записи делается так:
— сперва пишем во временный файл (внезапный exit() приведёт лишь к мусорному файлу, если ОС не умеет стирать временные файлы по закрытии процесса)
— затем атомарно переименовываем его в целевой.
Здравствуйте, Кодт, Вы писали: К>Почему это сам дурак? К>Крестик приводит к signal(SIGINT), то же самое будет, если пользователь нажмёт Ctrl+Break (или Ctrl+C). Вполне себе штатное действие.
Это вроде в юникс системах так, или я ошибаюсь? В сообщение на котороя я отвечал про винду говорилось. Но влюбом случаи, консольных прог в винде я особо много не писал, поэтому могу ошибаться как там все устроено
Здравствуйте, Nik_1, Вы писали:
К>>Крестик приводит к signal(SIGINT), то же самое будет, если пользователь нажмёт Ctrl+Break (или Ctrl+C). Вполне себе штатное действие. N_>Это вроде в юникс системах так, или я ошибаюсь? В сообщение на котороя я отвечал про винду говорилось. Но влюбом случаи, консольных прог в винде я особо много не писал, поэтому могу ошибаться как там все устроено
И в досе, и в виндах тоже.
На самом деле, продвинутая консольная программа должна пользоваться продвинутым консольным апи (curses или ConsoleAPI), а не только и не столько SIGINT'ом.
Здравствуйте, Nik_1, Вы писали:
N_>Здравствуйте, Кодт, Вы писали: К>>Почему это сам дурак? К>>Крестик приводит к signal(SIGINT), то же самое будет, если пользователь нажмёт Ctrl+Break (или Ctrl+C). Вполне себе штатное действие. N_>Это вроде в юникс системах так, или я ошибаюсь? В сообщение на котороя я отвечал про винду говорилось. Но влюбом случаи, консольных прог в винде я особо много не писал, поэтому могу ошибаться как там все устроено
В винде есть функция SetConsoleCtrlHandler, все виды нажатий пользователем, logoff и т.п. ловится через ее хэндлер.