Russian Qt Forum

Программирование => С/C++ => Тема начата: Alex Custov от Июнь 14, 2012, 15:26



Название: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: Alex Custov от Июнь 14, 2012, 15:26
Почти во всех примерах instance синглтона хранится как атрибут "instance" класса, и которому ещё нужно явным образом присваивать this. Зачем это, если можно сделать с помощью самого языка

Код
C++ (Qt)
class Example
{
   public:
       static Example *instance();
 
   private:
       Example(){}
};
 
//...
 
Example * Example::instance()
{
   static Example *inst = new Example;
   return inst;
}
 

?


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: Igors от Июнь 14, 2012, 15:31
А что будет если 2 или более нитки полезут в instance?


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: Alex Custov от Июнь 14, 2012, 15:36
А что будет если 2 или более нитки полезут в instance?

Всё тоже самое, как и классическом случае. Речь ведь не об этом. Все проблемы с синхронизацией решаются точно также.


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: iroln от Июнь 14, 2012, 15:59
Почти во всех примерах instance синглтона хранится как атрибут "instance" класса, и которому ещё нужно явным образом присваивать this. Зачем это, если можно сделать с помощью самого языка
Я, например, так и делаю. :)
Особого смысла хранить тоже не вижу.  ???


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: Igors от Июнь 14, 2012, 16:04
Всё тоже самое, как и классическом случае. Речь ведь не об этом. Все проблемы с синхронизацией решаются точно также.
А зачем их решать и (пере)проверять установки компилятора если можно обойтись средствами языка объявив inst членом класса? 


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: kambala от Июнь 14, 2012, 16:14
я вообще так пишу (многопоточность не используется если что):
Код
C++ (Qt)
class CharacterInfo
{
public:
   static CharacterInfo &instance()
   {
       static CharacterInfo obj;
       return obj;
   }
 
private:
   CharacterInfo() {}
};


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: Alex Custov от Июнь 14, 2012, 16:17
А зачем их решать и (пере)проверять установки компилятора если можно обойтись средствами языка объявив inst членом класса? 

А разве классический пример гарантирует thread-safe выполнение? Каким образом?


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: kambala от Июнь 14, 2012, 16:21
http://ru.wikipedia.org/wiki/Одиночка_(шаблон_проектирования)#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80_.D0.BD.D0.B0_C.2B.2B
Цитировать
Впрочем, в C++11 синглтон Майерса является потокобезопасным и без всяких блокировок.
:)


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: iroln от Июнь 14, 2012, 16:23
А зачем их решать и (пере)проверять установки компилятора если можно обойтись средствами языка объявив inst членом класса? 

А разве классический пример гарантирует thread-safe выполнение? Каким образом?
Классический пример ничего такого не гарантирует. Для потокобезопасности предлагают создавать экземпляр заранее, только тогда его надо хранить как член класса. А если экземпляр создавать в методе getInstance при первом обращении, тогда нужна синхронизация. Ну и зачем тогда хранить instance?


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: Alex Custov от Июнь 14, 2012, 16:35
Классический пример ничего такого не гарантирует. Для потокобезопасности предлагают создавать экземпляр заранее, только тогда его надо хранить как член класса. А если экземпляр создавать в методе getInstance при первом обращении, тогда нужна синхронизация. Ну и зачем тогда хранить instance?

Я ведь написал, что проблемы тут точно такие же. Они одинаково решаются вызовом Example::instance() где-нибудь в начале main(), и никакой синхронизации не надо, так чем классический пример лучше?


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: Alex Custov от Июнь 14, 2012, 16:37
http://ru.wikipedia.org/wiki/Одиночка_(шаблон_проектирования)#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80_.D0.BD.D0.B0_C.2B.2B
Цитировать
Впрочем, в C++11 синглтон Майерса является потокобезопасным и без всяких блокировок.
:)

Вот, теперь узнал что этот синглтон даже имя имеет ;D


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: Igors от Июнь 14, 2012, 16:47
На мой взгляд такая "элегантность" совсем ни к чему. Объявив inst членом мы ясно показываем чего хотим, и ключи компиляции нас не волнуют. Да и не всякий отладчик покажет статик с локальной областью видимости. Чего же достигли? Да ничего, так, повыдрючивались  :)

Первое что начинает делать любой начинающий - лепить глобальные переменные (обычно невпопад). Зачем придавать этому глубокомысленный вид ("классический сингтон майерса" и все такое)?  Где Вы тут усмотрели "классику"?  :)


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: Alex Custov от Июнь 14, 2012, 17:01
На мой взгляд такая "элегантность" совсем ни к чему. Объявив inst членом мы ясно показываем чего хотим, и ключи компиляции нас не волнуют.

Это уже религия. Лично по моему опыту если в классе есть статический метод instance(), то уже ясно что он делает. А что именно за ключи?

Да и не всякий отладчик покажет статик с локальной областью видимости. Чего же достигли? Да ничего, так, повыдрючивались  :)

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

Зачем придавать этому глубокомысленный вид ("классический сингтон майерса" и все такое)?  Где Вы тут усмотрели "классику"?  :)

Классикой я называю как раз статический атрибут, так делают почти везде. Но по идее он ничем не лучше, и по моему мнению даже хуже (функциональность та же, а лишнего кода больше) чем статическая переменная внутри instance().


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: Igors от Июнь 14, 2012, 17:19
А что именно за ключи?
В gcc "no-threadsafe-statics". Хотя по умолчанию такие статики защищаются, возможность получить по рыльцу все же есть. И уж совсем непрактично ковыряться в подробностях напр MSVC чтобы убедиться. Да объявил членом, инициализируется до main - и все дела


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: Alex Custov от Июнь 14, 2012, 17:29
Да объявил членом, инициализируется до main - и все дела

Каким образом он инициализируется до main()?


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: Igors от Июнь 14, 2012, 18:08
Каким образом он инициализируется до main()?
Тем же самым как все "non-local variables" (как-то так это звучит в стандарте). Статический член класса или член глобальная переменной класса в эту категорию входят. Впрочем стандарт не настаивает на "до main" допускаются реализации типа "на входе" но суть та же.

Алексей, Вы производите впечатление человека с опытом, ну почему тема яйца выеденного не стоит? Понимаю, хочется отдохнуть (серьезных забот хватает на работе), но все же обсуждение куда воткнуть 1 строку не выглядит хорошо :)  Поэтому умолкаю


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: Alex Custov от Июнь 14, 2012, 18:26
Я хочу добраться до истины >:( (ну и отдохнуть  ;D) В твоём случае статический и не динамический атрибут нужно явным образом глобально инициализировать наподобие "Example Example::m_instance;", я понял что значит "до main()", это почти тоже самое что и явное создание объекта Маерса через Example::instance() в начале main(). Итого, синглтон Маерса удобнее, т.к. содержит меньше ненужного кода, что есть добро. Мои рассуждения такие. То есть тема показала, как я и предполагал, что классическая реализация синглтона через статический атрибут просто традиция.


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: LisandreL от Июнь 14, 2012, 19:05
Итого, синглтон Маерса удобнее, т.к. содержит меньше ненужного кода, что есть добро.
С чего это меньше-то? Всё поровну:
Код
C++ (Qt)
class Example
{
   public:
       static Example *instance();
 
   private:
       Example(){}
};
 
 
Example * Example::instance()
{
   static Example *inst = new Example;
   return inst;
}
 
int main(int argc, char *argv[])
{
   Example::instance();
   // ...
}

Код
C++ (Qt)
class Example
{
   public:
       static Example *instance();
 
   private:
       Example(){}
       static Example *inst;
 
};
 
Example *inst = new Example;
 
Example * Example::instance()
{
   return inst;
}
 
int main(int argc, char *argv[])
{
   // ...
}

Синглтон Маерса удобен, если могут возникать случаи, что синглтон и не нужен. Тогда instance() не вызовется и объект не создастся.
Классика же удобна, когда синглотон должен существовать обязательно, тогда порождение его содержится в самом классе и не нужно думать что бы ещё такое дописать в мейн.


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: Alex Custov от Июнь 14, 2012, 19:30
С чего это меньше-то? Всё поровну:
Example * Example::inst = new Example;

Разве так можно? По-мойму по стандарту это UB, и поэтому классический синглтон неудобен, т.к. в нём нужно делать статический атрибут, и в конструкторе ему присваивать this. Или использовать нединамический вариант, который почему-то не слишком популярен. Т.к. я всегда использую динамический, мне вариант с

Код
C++ (Qt)
Example * Example::instance()
{
   static Example *inst = new Example;
   return inst;
}
 

удобнее. А если программа без потоков, то его даже инициализировать не нужно в main().


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: kambala от Июнь 14, 2012, 19:34
в вики есть ссылка на статью нашего ufna про переносимый синглтон: http://ufna.ru/2010/04/24/singleton-for-qt


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: LisandreL от Июнь 14, 2012, 21:46
По-мойму по стандарту это UB
Так по вашему или по стандарту?

Или использовать нединамический вариант, который почему-то не слишком популярен.
У нединамического варианта есть свои плюсы. При выходе из программы такой объект будет разрушен, что важно, если у него (или его «детей») деструктор имеет некоторую смысловую нагрузку.


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: Авварон от Июнь 14, 2012, 22:15
Госпади, ну сколько ж можно жевать...

Код:
Q_GLOBAL_STATIC(MyClass, static_instance)
MyClass * MyClass::instance()
{
    return static_instance();
}

А в qt5 там еще и проблем не будет у этого макроса.


Название: Re: Зачем хранить instance синглтона в атрибутах класса?
Отправлено: DmitryM от Июнь 28, 2012, 10:28
У нединамического варианта есть свои плюсы. При выходе из программы такой объект будет разрушен, что важно, если у него (или его «детей») деструктор имеет некоторую смысловую нагрузку.
Это можно сделать и с динамическим синглетоном ;)