Название: Класс настроек Отправлено: deMax от Сентябрь 16, 2014, 08:57 Как правильно реализовать сабж?
Настройки должны отображаться в окне настроек, их используют разные модули программы. Singletone? MVC? Название: Re: Класс настроек Отправлено: vizir.vs от Сентябрь 16, 2014, 09:47 Вариант с синглтоном мне нравится больше. Что за MVC - Model Viewer Controller? а как он здесь связан? Второй вариант через наблюдателя. Но тогда надо все классы наследовать от наблюдателя и определять соответствующие методы.
P.S. если у тебя настройки меняются и тебе потом надо рассылать обновления, то это либо через наблюдателя, либо синглтоно, но нужно слать сигналы всем окнам, чтобы они обновили инфу о настройках. Название: Re: Класс настроек Отправлено: navrocky от Сентябрь 16, 2014, 10:58 Делаешь класс на базе QObject с сигналом changed(), с сохранением в реестр/ini по методу commit(). Далее, зависит от архитектуры твоего приложения, или делаешь синглтоном объект этого класса или раздаешь указатель на него всем заинтересованным окнам, объектам.
В общем-то, если у тебя будет отдельное приложение - то скорее всего можно использовать синглтон. Если разделяемая библиотека, то однозначно надо тянуть указатель. Название: Re: Класс настроек Отправлено: kai666_73 от Сентябрь 16, 2014, 15:59 Если разделяемая библиотека, то однозначно надо тянуть указатель. Чёоо :oВ библиотеках нельзя использовать синглтоны? Или объявлять? Название: Re: Класс настроек Отправлено: Alexu007 от Сентябрь 16, 2014, 19:28 Сделать переменные настроек глобальными, меню настройки пусть их меняет, а разные модули программы только читают. В чём проблема? ;D
Название: Re: Класс настроек Отправлено: vizir.vs от Сентябрь 17, 2014, 09:29 Сделать переменные настроек глобальными, меню настройки пусть их меняет, а разные модули программы только читают. В чём проблема? ;D Задача синглтона сделать класс легкодоступным всем и при этом гарантировать единственность этого класса. А если ты сделаешь просто глобальную переменную кто угодно может ее создать или скопировать, но настройки то должны быть одни для всей программы! И не должно быть возможность создать еще одну переменную настроек или скопировать существующие. Название: Re: Класс настроек Отправлено: Igors от Сентябрь 17, 2014, 09:42 Сделать переменные настроек глобальными, меню настройки пусть их меняет, а разные модули программы только читают. В чём проблема? ;D В какой-то момент приходит неприятное ощущение "бардака", обнаруживается что разрозненных переменных уже слишком много и надо с ними что-то делать. Ну это конечно когда проект разрастется.Название: Re: Класс настроек Отправлено: navrocky от Сентябрь 17, 2014, 09:50 Если разделяемая библиотека, то однозначно надо тянуть указатель. Чёоо :oВ библиотеках нельзя использовать синглтоны? Или объявлять? Название: Re: Класс настроек Отправлено: Bepec от Сентябрь 17, 2014, 10:21 Несогласен с последним оратором.
Синглтон подразумевает, что архитектура приложения будет фиксированной. Это приводит к тому, что библиотека будет пользоваться ТОЛЬКО так, как и задумывалось. Что с одной стороны правильно - неправильно её использовать будет почти невозможно :D С другой стороны - приложение, её использующее должно соответствовать определённым требованиям. Правильный синглтон не обращает внимание на такие мелочи как "многопоточность". Но это уже заслуга его автора и продуманности архитектуры :D PS плохой дизайн это как раз куча глобальных переменных хрен знает откуда меняющихся и использующихся. В случае с синглтоном можно довольно просто исправить ситуацию, имея его определение :) Название: Re: Класс настроек Отправлено: kai666_73 от Сентябрь 17, 2014, 10:34 Если разделяемая библиотека, то однозначно надо тянуть указатель. Чёоо :oВ библиотеках нельзя использовать синглтоны? Или объявлять? Аргументы либо притянуты, либо далеки от контектста: > Плохой дизайн если только неграмотная реализация синглтона... > в многопоточной среде настройки в отдельном потоке? оно надо? > Синглтон накладывает серьезное ограничение на способ использования так ведь в этом его предназначение. Одиночка она и в приложении и в библиотеке одиночка ЗЫ. Ой, Верес опередил. Название: Re: Класс настроек Отправлено: Igors от Сентябрь 17, 2014, 11:00 Ну давайте копнем, что ли (а то много общих слов :)). Корректна ли такая реализация ?
Код
Название: Re: Класс настроек Отправлено: OKTA от Сентябрь 17, 2014, 11:13 Хм, я бы поставил QMutexLocker перед if. А так, подозрений не вызывает)
Название: Re: Класс настроек Отправлено: Bepec от Сентябрь 17, 2014, 11:20 ++ убрать перед if. На первый взгляд нормальная архитектурка.
Название: Re: Класс настроек Отправлено: kai666_73 от Сентябрь 17, 2014, 11:37 Ага и в результате получать фризы при каждом вызове Instance, даже когда физически инстанс создан. Но деваться некуда если хотим потокобезопасный синглтон... при данной реализации...
А если так? Код: QScopedPointer<MySingle> MySingle::m_instance(new MySingle()); Название: Re: Класс настроек Отправлено: m_ax от Сентябрь 17, 2014, 11:38 А про стандарт с++11 кто-нить вообще слышал? ;)
Название: Re: Класс настроек Отправлено: Авварон от Сентябрь 17, 2014, 11:43 Ну давайте копнем, что ли (а то много общих слов :)). Корректна ли такая реализация ? нет, реализация некорректна.Код
Название: Re: Класс настроек Отправлено: Bepec от Сентябрь 17, 2014, 11:58 Приводите аргументы, вместо недоказанных утверждений, пожалуйста :)
Замечу - фриз будет если вызывать instance раз 200-300 без перерыва. А на хорошей архитектуре он будет вызываться 1 раз при создании объекта. update: Да. Некорректная реализация именно из-за блокировки после условия. Там вполне возможна аварийная ситуация при захвате и ожидании мутексов. Создадутся N копий синглтона. Но вынос блокировки наверх решает эту проблему :D Название: Re: Класс настроек Отправлено: Авварон от Сентябрь 17, 2014, 12:01 Приводите аргументы, вместо недоказанных утверждений, пожалуйста :) Замечу - фриз будет если вызывать instance раз 200-300 без перерыва. А на хорошей архитектуре он будет вызываться 1 раз при создании объекта. QMutex - это не POD, делать статик не-POD нельзя. Что будет, если 2 потока начнут инициализировать мьютекс? Можно заменить на QBasicMutex. Название: Re: Класс настроек Отправлено: Igors от Сентябрь 17, 2014, 12:01 Хм, я бы поставил QMutexLocker перед if. А так, подозрений не вызывает) Типа "да хз, вот так точно будет работать". Так-то оно так, но ведь захват мутекса - трудоемкая операция, а синглтон может зваться очень часто.++ убрать перед if. На первый взгляд нормальная архитектурка. Какими короткими стали Ваши ответы, куда же девалась обычная словоохотливость ? :)А если так? Ну если объявлять его глобально (до main) - то и никакие scoped не нужны. Но такое объявление не всегда выгодно/возможноКод: QScopedPointer<MySingle> MySingle::m_instance(new MySingle()); А про стандарт с++11 кто-нить вообще слышал? ;) А без нового стандарта чего-то можем? Или тогда в дуст полезем? :) Название: Re: Класс настроек Отправлено: Bepec от Сентябрь 17, 2014, 12:05 Синглтон НЕ ДОЛЖЕН зваться часто. Он инициализироваться должен 1 (ОДИН) раз.
1 раз для каждой подгружаемой сущности. В результате количество вызовов синглтона должно быть равным количеству сущностей. Фризов НЕ БУДЕТ. А если он будет вызываться 60 раз в секунду - тогда голову надо пожмякать тому, кто напишет такую программу. Ибо даже если самую простейщую операцию вызывать нонстоп - заглохнет всё. PS вот тут и возникает ситуация о которой я писал - синглтон зависим от архитектуры. И вменяемости программиста. update: Словоохотливость вкл. Рассуждения о "трудоёмкости", "фризах" и прочем - это мифы. Те, кто утверждают что "синглтон будет вызываться часто" - видимо имеют случай "голова не знает что руки делают". to Max: приведите пример синглтона с новым стандартом пожалуйста. Мне интересно. to Аварон: настолько глубоко я мутексы и статик не знал, спасибо за пояснение. Словоохотливость выкл. Название: Re: Класс настроек Отправлено: Igors от Сентябрь 17, 2014, 12:06 QMutex - это не POD, делать статик не-POD нельзя. Что будет, если 2 потока начнут инициализировать мьютекс? Можно заменить на QBasicMutex. Есть опция "statics are thread-safe" культурно защищает инициализацию спыннером. Но вообще да, лучше не искать приключений и вынести mutex за тело ф-ции.Но в том что я привел еще 2 пробоя. Первый детский, режет глаз. Второй - на мой взгляд логикой найти невозможно, тот печальный случай когда зубрилка побеждает (ну так иногда бывает :)) Название: Re: Класс настроек Отправлено: Bepec от Сентябрь 17, 2014, 12:10 Как обычно, Igors свёл рассуждение о синглтоне к поиску ошибок в куске левого кода :)
Название: Re: Класс настроек Отправлено: Авварон от Сентябрь 17, 2014, 12:14 QMutex - это не POD, делать статик не-POD нельзя. Что будет, если 2 потока начнут инициализировать мьютекс? Можно заменить на QBasicMutex. Есть опция "statics are thread-safe" культурно защищает инициализацию спыннером. Но вообще да, лучше не искать приключений и вынести mutex за тело ф-ции.Но в том что я привел еще 2 пробоя. Первый детский, режет глаз. Второй - на мой взгляд логикой найти невозможно, тот печальный случай когда зубрилка побеждает (ну так иногда бывает :)) Не во всех комиляторах. В гцц вышеприведенный код и без всяких опций будет работать, что не означает, что он верен. Название: Re: Класс настроек Отправлено: Igors от Сентябрь 17, 2014, 12:21 [Не во всех комиляторах. В гцц вышеприведенный код и без всяких опций будет работать, что не означает, что он верен. Ладно, чтобы "сердце успокоилось" исправляемКод Теперь верно ? Название: Re: Класс настроек Отправлено: OKTA от Сентябрь 17, 2014, 12:31 Код: MySingle * MySingle::mInstance = 0; Ну, можно еще так, с двойной проверкой для двойного успокоения сердца Название: Re: Класс настроек Отправлено: Johnik от Сентябрь 17, 2014, 12:32 начали за здравие...
для "синглтонов" в Qt можно использовать Q_GLOBAL_STATIC хорошее описание синглтонов есть в книге Александреску Название: Re: Класс настроек Отправлено: Igors от Сентябрь 17, 2014, 12:44 Код: MySingle * MySingle::mInstance = 0; Ну, можно еще так, с двойной проверкой для двойного успокоения сердца Название: Re: Класс настроек Отправлено: Igors от Сентябрь 17, 2014, 13:01 для "синглтонов" в Qt можно использовать Q_GLOBAL_STATIC Так это то же самое малодушное решение Верес'а (вынос блокировки вверх) - с той лишь разницей что используется атомарный локерНазвание: Re: Класс настроек Отправлено: Bepec от Сентябрь 17, 2014, 13:07 Ххы. Самый смак в том, что вашего идеального решения не существует, увы. А малодушное решение работать будет.
Название: Re: Класс настроек Отправлено: vizir.vs от Сентябрь 17, 2014, 13:15 http://habrahabr.ru/post/150276/
Название: Re: Класс настроек Отправлено: Bepec от Сентябрь 17, 2014, 13:48 Если в двух словах - gcc ставит мутекс на каждый вызов :D
Название: Re: Класс настроек Отправлено: kambala от Сентябрь 17, 2014, 13:49 еще можно воспользоваться GCD (https://ru.wikipedia.org/wiki/Grand_Central_Dispatch) и создавать синглтон в dispatch_once()
Название: Re: Класс настроек Отправлено: m_ax от Сентябрь 17, 2014, 13:51 Цитировать to Max: приведите пример синглтона с новым стандартом пожалуйста. Мне интересно. Код
Название: Re: Класс настроек Отправлено: Igors от Сентябрь 17, 2014, 14:02 http://habrahabr.ru/post/150276/ И что с того? [off]Давно заметил что "тыц ссылкой" - совсем не признак ума :)[/off] Код
Название: Re: Класс настроек Отправлено: Bepec от Сентябрь 17, 2014, 14:38 Ммм... Т.е. стандарт разруливает все мутексы и прочую фигню? :)
Название: Re: Класс настроек Отправлено: OKTA от Сентябрь 17, 2014, 14:48 Ссылка от Vizir.vs говорит и показывает, что не все компиляторы по-честному поддерживают эту тему, так что чего-то сомнительно ;D
Название: Re: Класс настроек Отправлено: OKTA от Сентябрь 17, 2014, 15:56 Цитировать А если в какой-то момент я захочу заменить instance, а потом вернуть старый ? (типа push/pop) Это тонкий намек, что от мьютексов не убежать? ;D Название: Re: Класс настроек Отправлено: Bepec от Сентябрь 17, 2014, 16:24 Это тонкий намёк на натуру Igors - поставить задачу, а потом менять условие, не считаясь ни с какими доводами :D
Не хотел бы я, чтоб он был заказчиком :) Название: Re: Класс настроек Отправлено: OKTA от Сентябрь 17, 2014, 16:28 Хм, что же это, все операции для чтения-установки значений в классе настроек таком тоже придется защищать мьютексами? ;D
Название: Re: Класс настроек Отправлено: Bepec от Сентябрь 17, 2014, 16:49 новый стандарт делает просто - на каждый вызов по мутексу :D Видимо не тормозит :D
Название: Re: Класс настроек Отправлено: Авварон от Сентябрь 17, 2014, 16:54 [Не во всех комиляторах. В гцц вышеприведенный код и без всяких опций будет работать, что не означает, что он верен. Ладно, чтобы "сердце успокоилось" исправляемКод Теперь верно ? B снова неверно. Порядок инициализации не определён. Может статься, что вы при вызове Instance(), QMutex еще не создан. Блин, читайте Александреску. ЗЫ: а dlopen является thread-safe? Название: Re: Класс настроек Отправлено: OKTA от Сентябрь 17, 2014, 17:00 в этом случае QMutex сразу будет создан по причине своей статичности и нахождении в теле класса, разве нет?
Название: Re: Класс настроек Отправлено: Igors от Сентябрь 17, 2014, 17:03 Хм, что же это, все операции для чтения-установки значений в классе настроек таком тоже придется защищать мьютексами? ;D Никто не утверждал что синглтон нельзя менять, и это может быть небезопасно если он используется неск нитками. Так что эти заботы никто не отменял. Только вот чего это я обязан объявлять static экземпляр? Как всегда указатель гибче. Подлянка в операторе new (см. статью кстати очень неплохую). В 2 словах Код Стандарт во всяком случае не запрещает установку возвращаемого значения mInstance ДО ТОГО как код конструктора полностью выполнится. Ну так это легко обходится если чуть-чуть подумать. Но увы - желания думать нету. Пошла барахолка типа "где бы чего достать" под трескотню Верес'а :'( B снова неверно. Порядок инициализации не определён. Может статься, что вы при вызове Instance(), QMutex еще не создан. Я даже знаю из какой (глупейшей) статьи Вы это почерпнули :) Не верьте всему прочитанномуНазвание: Re: Класс настроек Отправлено: Bepec от Сентябрь 17, 2014, 17:06 Предоставьте мне желательно другой способ безопасного многопоточного вызова любого метода без использования мутекса :D
Закавыка в том, что вы предлагаете найти то, что уже нашли вы. Это мало того, что бессмысленно - мутексы проще и гибче, да ещё и попахивает "профессионалом". Типа я додумался, но никому не скажу, пусть мучаются. Но блин кому надо искать что-то, что нашли вы, когда на полке лежат прекрасно разобранные мутексы? Они имеют свои ограничения, но эти ограничения уже давно описаны и понятны. Название: Re: Класс настроек Отправлено: Alexu007 от Сентябрь 17, 2014, 17:16 Сделать переменные настроек глобальными, меню настройки пусть их меняет, а разные модули программы только читают. В чём проблема? ;D В какой-то момент приходит неприятное ощущение "бардака", обнаруживается что разрозненных переменных уже слишком много и надо с ними что-то делать. Ну это конечно когда проект разрастется.Название: Re: Класс настроек Отправлено: m_ax от Сентябрь 17, 2014, 17:25 Цитировать А если в какой-то момент я захочу заменить instance, а потом вернуть старый ? (типа push/pop) Или я чего то не понимаю, или вы слишком много требуете от простого синглтона.. Название: Re: Класс настроек Отправлено: Bepec от Сентябрь 17, 2014, 17:53 Это же Igors.
У него сначала велосипед едет на треугольных колёсах, спрямляем - поехал быстрее. У велосипеда оказывается были лопасти из картона и он должен был летать, заменили картон на пластик - полетели меееедленно. Оказывается всё это происходит в коронной области солнца и велосипед должен быть герметичен - со стонами мастерим систему охлаждения, работающую на научных парадоксах и герметизируем с помощью строительной пены. Ан нет, мы неправы. Потому что забыли систему защиты от злобных пришельцев на трёхколёсных велосипедах :D Название: Re: Класс настроек Отправлено: Авварон от Сентябрь 17, 2014, 18:22 Я даже знаю из какой (глупейшей) статьи Вы это почерпнули :) Не верьте всему прочитанному То есть вы утверждаете, что если один синглтон обращаются конструктора к другому, то проблем не будет? :facepalm: Название: Re: Класс настроек Отправлено: Igors от Сентябрь 18, 2014, 09:16 То есть вы утверждаете, что если один синглтон обращаются конструктора к другому, то проблем не будет? :facepalm: ПримерКод Какие здесь проблемы с инициализацией? Никаких, любая "нелокальная" (в терминах стандарта) переменная может использовать объявленные ранее. Порядок не определен для переменных объявленных в разных единицах трансляции - ну так об этом здесь речь не идет (см ниже). Предоставьте мне желательно другой способ безопасного многопоточного вызова любого метода без использования мутекса :D Если Вы хотели показать себя "опытным практиком", то у Вас была прекрасная возможность. Практик не заморачивался бы с никакими блокировками, а написал бы такКод Да, это "небезопасно", но достаточно вызвать MySingle::Instance один раз (напр на старте) - и проблемы нет. Или обеспечить вызов перед перед запуском использующих его ниток. Затрудняюсь привести пример когда это невозможно. А часто (пусть и не всегда) можно тупо объявить его глобальной переменной которая гарантировано будет инициализироваться только в главной нитке до main. Однако вместо этого Вы несете такую пургу А если он будет вызываться 60 раз в секунду - тогда голову надо пожмякать тому, кто напишет такую программу. что даже неудобно слушать :)Или я чего то не понимаю, или вы слишком много требуете от простого синглтона.. Вы указываете что в новом стандарте проблема инициализации глобальных переменных решена. Это бесспорно, но речь шла о создании синглтона в куче, резоны найдутся. Выходит объявить "безопасную" глобальную переменную могу, а указатель нет. Или как?Название: Re: Класс настроек Отправлено: Bepec от Сентябрь 18, 2014, 09:35 Ваш способ не безопасен. С таким же успехом я могу использовать указатель-глобальную переменную. Но синглтон в не знает кто и когда его вызовет, что накладывает ограничение.
Самое простой пример - использование dll с синглтоном. И никто-никогда не узнает до вызова instance - есть ли в приложении синглтон или нет :) Как обычно по сути дела ничего. Уже и приплели "достаточно вызвать 1 раз". Такое чувство не читали тему - на первых страницах приводили вариант вызова из длл. Название: Re: Класс настроек Отправлено: m_ax от Сентябрь 18, 2014, 14:19 Цитировать но речь шла о создании синглтона в куче, резоны найдутся. Выходит объявить "безопасную" глобальную переменную могу, а указатель нет. Или как? Для указателей можно использовать std::call_once http://en.cppreference.com/w/cpp/thread/call_once (http://en.cppreference.com/w/cpp/thread/call_once)Есть и примеры синглетонов с её использованием.. Название: Re: Класс настроек Отправлено: deMax от Октябрь 14, 2014, 15:42 Собственно в продолжении темы: как обращаться из программы к настройкам? Удобно пользоваться автодополнением, но когда настройки хранятся в виде QMap<QString,QVariant> при обращении к настройками писать строковый ключ неудробно - нужно его помнить и можно ошибиться, автодополнение - структуры городить.
Название: Re: Класс настроек Отправлено: vizir.vs от Октябрь 14, 2014, 15:54 Не совсем понял. У тебя в программе есть окно, в котором ты начинаешь вводить название параметра и у тебя должны выпадать возможные варианты продолжения?
Название: Re: Класс настроек Отправлено: deMax от Октябрь 14, 2014, 15:58 Не совсем понял. У тебя в программе есть окно, в котором ты начинаешь вводить название параметра и у тебя должны выпадать возможные варианты продолжения? Я в коде хочу прочитать что то из настроек, если писать строчку то можно ошибиться.Название: Re: Класс настроек Отправлено: OKTA от Октябрь 14, 2014, 16:20 enum тебе в помощь.
|