- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
class ControlerSingleton
{
private:
static int ControlCode;
static bool disaPear;
static int ArraySize;
//...
void Constructor()
{
//...
ArraySize=sizeof(masi)/sizeof(masi[0]);
disaPear=Pear();
threadRAII.Wait();
ControlCode=threadRAII.result();
//...
};
static int construct=Constructor();
public:
const bool Pear()
{
//...
};
Stalker 23.06.2010 18:12 # 0
И как его в int construct присвоили?
Что тут происходит вообше? Интересно просто :)
Говногость 23.06.2010 18:52 # 0
По памяти писал. Статик там есть.
Говногость 23.06.2010 18:54 # 0
И int там есть. Тоже попутал что-то...
Говногость 23.06.2010 18:59 # 0
Это "типа" паттерн Синглтон. Не он, но чем-то похож. Инициализация статических членов класса происходит при вызове функции constructor. Эта функция реально результата не возращает, но как-бы имеет возвращаемы тип int. Этот "псевдо-конструктор" вызывается, во время инициализации статического члена int construct.
Webkill 23.06.2010 19:03 # −9
в дотнете в этом смысле поумнели. ну сравните, допустим, яву:
ява: Runtime.getRuntime().totalMemory().
дотнет: GC.GetTotalMemory(0
Ну скажи, ты этот обхект - Runtime - сериализовать что ли собираешься? Нахрен он нужен?
Или в с++ сложнее со статическими функциями/полями? В сишарпе и яве есть статический конструктор. А тут? Как ни крути, синглтоны - дебилизм, юзающийся по инерции там, где он не нужен.
Говногость 23.06.2010 19:08 # 0
Ты так спрашиваешь, будто я это написал. :D
Webkill 23.06.2010 19:21 # −5
Kirinyale 23.06.2010 19:58 # 0
Мне даже приходилось такое делать. Бывает очень полезно.
pushkoff 23.06.2010 20:04 # +1
из преимуществ вызовы вфглядят так
Manager::SomeMethod()
из недостатков, нужно делать методы Init/Close которые не вызовутся автоматически (хотя в синглтонах их иногда тоже надо вызывать, либо где-то создавать сам синглтон), нельзя создать класс наследник (но это реально редко надо)...
Webkill 23.06.2010 20:50 # −6
Ну вот, в с++ ввели понятие статики, но в то же время не удосужились сделать статический конструктор. В с++ причём ведь подобные асимметрии на каждом углу случаются - как будто фичи делали второпях, или бросали делать на полпути, такое ощущение.
Хм, в сишарпе статических деструкторов как таковых нет...
Хм, в сишарпе статических деструкторов как таковых нет... Как выход - подписаться на событие AppDomain.CurrentDomain.DomainUnload разве что...
> нельзя создать класс наследник (но это реально редко надо)...
Не могу придумать пример.
Хотя в голову пришла например консоль. Если консоль - синглтон, то можно сделать ей интерфейс IStream и работать как с потоком: ((IStream)Console.GetConsole()).ReadByte s(). Это да.
Но в то же время в бессинглтоновой модели это легко реализуется аггрегацией: Console.GetIntputStream().
Так что небольшое это и преимущество...
pushkoff 23.06.2010 22:16 # 0
то есть можно писать так
int* i = new int();
в момент вызова main в i будет валидный указатель на int...
pushkoff 23.06.2010 22:16 # 0
Webkill 23.06.2010 22:28 # −5
> это называется отложенная инициализация...
Не очень-то она отложенная. Т.е. если у меня в проекте (допустим, большущая библиотека) 1000 классов, то на стартапе у меня будут конструироваться статические конструкторы всех 1000 классов?
Можно сделать отложенно через синглтоны -- проверять на null и конструировать синглтон НО! это потоконебезопасно, во время такого конструирования с другого потока могут этот же синглтон вызвтаь, в итоге конструктор вызовется два раза. Е*аться с критиченскими секциями? Их тоже нужно где-то иницилизировать, хаха (под винапи нету статической инициализации критич. секций в отличие от ПОЗИКС)
Крутой же с++ ))
В сишарпе статический конструктор вызывается при первом обращении к классу (в моно делается специальный трамполин (сгенерированный участок кода, скрепляющий два других участка кода). После вызова стат. конструктора трамполины, т.е. инициализирующий код, полностью вырезаются из памяти, т.е. рантайм-проверок при следующих обращениях к классу уже больше не будет.
А чем можем похвастаться с++?
pushkoff 23.06.2010 22:54 # 0
если у тебя в каждом из 1000 классов, 1 статический член, который не может быть инициализирован в компайл тайме, он будет инициализироваться до вызова main... все конструкторы (кроме статических членов функции) вызываются в том же потоке, в котором позже вызовется main... под винапи критические секции инициализируются специальной оберткой (фейл с твоей стороны считать что это невозможно).
Webkill 24.06.2010 00:13 # −5
покажи тогда, мне пригодится на будущее (с++ не предлагать, только с...)
Webkill 24.06.2010 00:21 # −4
pushkoff 24.06.2010 11:59 # −1
как использовать сам догадаешься??
Webkill 24.06.2010 14:06 # −2
так или иначе, это даст мне статическую инициализацию? т.е.
так?
Это псевдостатика, реально же это рантайм-инициализация, т.е. оно рантаймно вызывает функции в __main. А я просил истинно статическую инициализаци.
Вот ты столько кода наприсал, а в позиксе это реализуется одной строчкой:
в том числе в чистом си допустимо использовать. Никаких функций не вызывается, никаокго рантайма.
Я это имел в виду.
pushkoff 24.06.2010 15:35 # 0
Webkill 24.06.2010 15:39 # −3
pushkoff 24.06.2010 15:53 # 0
мне нравится то что в С++ вся инициализация пройдет на этапе загрузки, так как паттерн
меня не устраивает полностью и я его считаю говнокодом...
Webkill 24.06.2010 17:34 # −3
pushkoff 24.06.2010 17:56 # −1
Говногость 24.06.2010 18:15 # +1
Webkill 24.06.2010 18:20 # −2
pushkoff 24.06.2010 18:47 # 0
ну мне допустим не нравится что какой-то простой метод, вдруг случайно обратится к неинициализированному синглтону и будет висеть в его инициализации, из-за этого я (да и многие С++ программисты, которые в курсе) не люблю статические данные в функции, так как они (вроде ГСС страдает такой хней)инициализируются при первом вызове... это плохо... С++ гарантирует что статические данные инициализируются до вызова меин, и проблем во время работы не будет!
Webkill 24.06.2010 18:53 # −3
ну вообще-то в шарпе синглтоны в статические конструкторы обычно не пихают) я просто как пример выгоды приводил.
pushkoff 24.06.2010 18:58 # −1
Webkill 24.06.2010 19:03 # −3
Непонял, где ты этот оверхед взял? Он случается только один раз. Так же и методы - оверхед происходит только один раз, во время компиляции. Дальше уже патчится указатель на скомпилированный участок.
И вообще, причём здесь кеши и конвееры? Это то же самое, как если бы нативная программа впервые вызвала некую функцию. В моно всё реалдизуется трамполинами, это участки кода-переходы, они создаются на один раз, а потом удаляются (или патчатся, или просто удаляютя)...
А сиплюс например умеет share инстансы шаблонов? Или для кажого типа генерит свою нативную реализацию? А вот моно умеет share. В памяти и на диске меньше памяти, и кеш круче.
pushkoff 24.06.2010 19:09 # +1
а я и говорю что один раз... просто никто не знает когда именно...
pushkoff 24.06.2010 19:09 # 0
Webkill 24.06.2010 19:14 # −2
Говногость 24.06.2010 15:18 # 0
Это бы автоматизировать, что-бы нельзя было ошибиться.
Webkill 24.06.2010 15:22 # −3
pushkoff 24.06.2010 15:29 # 0
пожалуста...
pushkoff 24.06.2010 15:30 # 0
void func(void)
{
AutoLock<CriticalSection> auto_cs;
if(expression)
throw Exception;
};
Webkill 24.06.2010 15:31 # −3
т.е. func может вызвать самого себя, в котором будет ещё один лок. Сработает? Пупок не развяжется?
pushkoff 24.06.2010 15:55 # 0
Webkill 24.06.2010 15:58 # −3
я не про крит. секцию, а про AutoLock. Он справится?
pushkoff 24.06.2010 16:00 # 0
pushkoff 24.06.2010 16:00 # 0
Webkill 24.06.2010 16:04 # −1
Говногость 24.06.2010 17:45 # 0
К томуже в AutoLock приходится указывать каждый раз параметр шаблона, что не удобно.
pushkoff 24.06.2010 17:53 # 0
новичку один раз стоит показать как надо, и он с этого, как с иглы, никогда не слезет...
на gamedev.ru есть подсказка на эту тему...
pushkoff 24.06.2010 17:58 # 0
Говногость 24.06.2010 18:17 # 0
Да, и это будет не хорошо из-за возможности появления исключений.
pushkoff 24.06.2010 18:53 # 0
для обхода проблем с исключениями и досрочным выходом и придуман этот паттерн, не пользуешься - сам себе макака...
Говногость 24.06.2010 20:34 # 0
Вообщето я об этом паттерне и говорил. "Двойная проверка". Именно Александреску его и описывает. :D
pushkoff 24.06.2010 21:17 # 0
Говногость 24.06.2010 15:26 # 0
Webkill 24.06.2010 15:32 # −3
Что это?
Критические секции не такие уж и медленные
Говногость 24.06.2010 16:20 # 0
Webkill 24.06.2010 16:23 # −3
запись-чтение всё равно могут быть произведены одновременно, будет повреждение указателя всё равно
и громоздко
и рантайм-проверка
и хаки
что вам статические конструкторы по требованию не нравятся???
Говногость 24.06.2010 16:42 # +2
Какой же вы всё-таки тролль... Я никогда это не опровергал. Не на одном С++ мир замкнулся.
Вы одиноки? Ищите повод поговорить? Советую обратиться к хорошему психологу.
Webkill 24.06.2010 18:01 # −3
Говногость 24.06.2010 18:18 # +1
pushkoff 24.06.2010 17:14 # 0
Говногость 24.06.2010 17:48 # 0
Webkill 24.06.2010 17:52 # −3
Говногость 24.06.2010 18:18 # +1
Нет.
Говногость 24.06.2010 17:50 # 0
Это из разряда: я не доверяю автоматическим средствам и сделаю всё сам. Я предлагал использовать оптимизирующий паттерн. Паттерн и паранойя - это разные вещи.
Webkill 24.06.2010 00:16 # −5
Я-то говорил про создание отложенных синглотонов. Как может отложенный сингдтон вызываться по требованию из другого потока (в нашем случае - main)? Здесь нужен какой-то хитрый рантайм уже (что-то вроде сигналов/прерываний, чтобы остановить главный поток, перезаписать регистры след. инструкции, прыгнуть на код создангия, потом вернуть обратно - бред )) ).
pushkoff 24.06.2010 12:01 # 0
Webkill 24.06.2010 13:59 # −2
если я хочу по-настоящему отложенные синглтоны, о которых шла речь - то я не смогу их все создавать в main. неизвестно, какой поток дёрнет первым.
и причём здесь ум? неговнокодерскому синглтону должно быть без разницы, в контексте какого потока он создаётся. здесь проблема только в синхронизации записи указателя получается.
pushkoff 24.06.2010 12:12 # −1
Webkill 24.06.2010 14:01 # −3
pushkoff 23.06.2010 22:57 # 0
Webkill 24.06.2010 00:15 # −5
Ну вот это я бы и не назвал "отложенной инициализацией", потому что она нифига не отложенная. В сишарпе если ты за весь ход программы ни разу не обращался к классу X, то его статический конструктор ни разу и не вызовется... А с++ прёт напролом. Минус сиплюсу в этом плане.
pushkoff 24.06.2010 11:52 # 0
Webkill 24.06.2010 13:56 # −3
а если у нас библиотека? а в конечной энд-юзеровской проге если какие-то функции объявлены, но не используются - это говнокод же. компилятор сишарпа делает часто ворнинг о таких вещах. а если помечено как дебуг или тест, то компилятор стрипит.
так что не сливает тут сишарп, это сиплюс потакает говнокоду и хакам просто.
pushkoff 24.06.2010 15:24 # −1
Webkill 24.06.2010 15:28 # −3
Иначе зачем нужно писать код, который не попадает в билд, скажи.
с++ придумывает говноподход, потом придумывает говнорешение-костыль к этому говпноподходу и потом представляет это как некую крутую фишку - знаем, проходили.
pushkoff 24.06.2010 15:48 # 0
Webkill 24.06.2010 15:51 # −3
нету.
не используется только если в каких-то библиотеках (конгкретным приложением). но было бы глупо стриппить библиотеки, не так ли?
pushkoff 24.06.2010 15:59 # 0
Webkill 24.06.2010 16:06 # −3
в сишарпе другой подход - умное разделение на сборки. т.е. движок содержится не одной кучей в одном ДЛЛ, а разбросан по более конкретизированным модулям. Если что-то не нужно - просто не подключай либу и не распространяй. Так или иначе, байткод очень компактный, если с либой тащутся ненужные функции - это немного в размере.
pushkoff 24.06.2010 17:12 # 0
Webkill 24.06.2010 17:28 # −3
ну и глупо.
(и как я уже говорил, если не нравится иметь много файлов, в моно можно с помощью mkbundle эксешник и набор дллшек зашить в одно эксе. можно также статически линковать mono.dll, но уже нужно платить деньги вороде бы)
pushkoff 24.06.2010 17:49 # 0
в результате 10Мб виндовый билд
7,5Мб билд под iPhone...
Webkill 24.06.2010 17:54 # −3
pushkoff 24.06.2010 18:01 # −1
Webkill 24.06.2010 17:56 # −3
Webkill 24.06.2010 17:36 # −3
pushkoff 24.06.2010 17:49 # 0
Webkill 24.06.2010 15:28 # −4
pushkoff 24.06.2010 15:49 # 0
Webkill 24.06.2010 15:55 # −2
5.5 кб.
МоноДевелоп и то ещё всякого мусора напихал типа неймспейса Stetic зачем-то...
pushkoff 24.06.2010 15:57 # −2
Говногость 24.06.2010 15:20 # 0
Анонимус 24.06.2010 01:52 # 0
Потому что объект может представлять интерфейс, а класс -- нет.
заметьте -- я даже не знаю -- Pool это синглтон или у него N инстрансов и пуллинг (инстанс-контроллинг класс).
>>видеть синглтоны например в яве - это же смешно и неуклюже.
Только тому, кто слабоват в ООП;)
Webkill 24.06.2010 01:59 # −3
Я про то, что в большинстве случаев это не нужно, но синглтоны всё равно пихают зачем-то.
> заметьте -- я даже не знаю -- Pool это синглтон или у него N инстрансов и пуллинг (инстанс-контроллинг класс).
тогда это уже не паттерн синглтон, а скорее фабрика
> Только тому, кто слабоват в ООП;)
Гордиться силой в ООПе всё равно что гордиться познаниями в бейсике. Кстати у меня знание ООП 65%!
Анонимус 24.06.2010 02:20 # +1
Ну для классов-утилит это однозначно не нужно.
А если у сущности есть состояние, то лучше сделать ее синглтоном, что бы потом можно было врубить инстранс-контроллинг.
>>тогда это уже не паттерн синглтон, а скорее фабрика
Не фабрика, а фабричный метод, тогда уж. Потому что фабрика создает несколько разных объектов. Но фабричный метод может прятать внутри синглтон или пул инстансов или по инстансу на клиента (определять его по параметрам) итд.
>>Гордиться силой в ООПе всё равно что гордиться познаниями в бейсике.
Не скажите, многие крупные программы как раз страдают из-за плохого понимания ООП и (как следствие) дурной архитектуры.
>>. Кстати у меня знание ООП 65%!
по какой школе?:)))
Звучит как "на 5% более красивые волосы"
Webkill 24.06.2010 02:29 # −3
пофиг, как называть, хоть самокатом
> Ну для классов-утилит это однозначно не нужно.
Вот чем явовский Runtime не "класс-утилита"? Он ничего не наследует и не реализует, состояния особого не имеет. Однако сделали синглтоном, ведь сука в смоллтоке же так же!
> Не скажите, многие крупные программы как раз страдают из-за плохого понимания ООП и (как следствие) дурной архитектуры.
Ага, или от слишком хорошего понимания, что для того чтобы сложить два числа нужно использовать 10 фабрик и 5 адаптеров
Анонимус 24.06.2010 02:35 # +1
ну послушайте, паттерны для того и паттерны, что бы иметь внятные названия, и что бы программисты понимали, о чем речь.
>>Вот чем явовский Runtime не "класс-утилита"?
У него есть состояние, например метод "addShutdownHook" явно куда-то что-то сохраняет:)
>>Ага, или от слишком хорошего понимания, что для того чтобы сложить два числа нужно использовать 10 фабрик и 5 адаптеров
Такое тоже бывает, но редко:)
Чаще наоборот.
Вы наверное в сях тоже не каждую функцию в отдельный модуль выносите
Webkill 24.06.2010 02:45 # −3
И что толку? Если бы это была реализация интерфейса IShutdownHookable - то другое дело. ООП ведь, блядь, придумали не просто так - а чтобы решать практические задачи. Если у вас самоцель ООП, а не практтические вещи, реализуемые ООПом, то пожалуйста, ебашьте синглтон там, где он не нужен.
>ну послушайте, паттерны для того и паттерны, что бы иметь внятные названия, и что бы программисты понимали, о чем речь.
паттерны это очевидная вещь, названия для них нужно знать чтобы уметь их обсудить с неумеющими видеть очевидности программистами; таковых не знаю.
Анонимус 24.06.2010 02:54 # +1
Если я завтра захочу хранить по массиву шатдаун-хуков для каждого треда -- я просто перепишу один метод, что бы каждому треду возвращали по своему рантайму:) Это вырожденный пример, но более жизненного сходу не придумать.
Надеюсь, суть он отражает.
>>паттерны это очевидная вещь, названия для них нужно знать чтобы уметь их обсудить с неумеющими видеть очевидности программистами;
Некоторые паттерны не так уж очевидны, и если бы у них не было названий -- приходилось бы каждый раз на пальцах пересказывать их суть.
Вот например емкая фраза: "Различающееся поведение вынеси в стратегию".
Или "Вместо getType сделать визитор".
Или "Оформить ввиде композита и подымать событие ввиде chain-of-responsiblity ".
Все это было бы трудно описать на пальцах -- все таки паттерны не дураки придумали)
Webkill 24.06.2010 04:12 # −3
слова "подымать" и "композит" охуенно сочетаются
> Все это было бы трудно описать на пальцах -- все таки паттерны не дураки придумали)
ну да, людям же нужно меж собой разговаривать
> Если я завтра захочу хранить по массиву шатдаун-хуков для каждого треда -- я просто перепишу один метод, что бы каждому треду возвращали по своему рантайму:)
это опять будет не совсем синглтон. и опять надуманный пример, придуманный чтобы оправдать стремление возвысить инструмент над задачей
и по-моему это глупо делать ради одного свойства уже весь объект отдельным на поток. пусть этим занимаются аксессоры. логически Runtime один и нехуй плодить их десятки.
Анонимус 24.06.2010 13:05 # +1
А что такого?
Это как бы у Вас претензия к паттернам такая?:)
>>ну да, людям же нужно меж собой разговаривать
Обычно нужно. Над хорошими проектами работает несколько человек, и архитектуру тоже придумывает несколько. В идеале (по правилам XP) там вообще парное программирование.
>>это опять будет не совсем синглтон
Именно синглтон, просто пример правда не очень живой.
>>и по-моему это глупо делать ради одного свойства уже весь объект отдельным на поток.
А если будет два свойства?
Вы будете копипастить код в каждом методе?:)
Но вообще Runtime и правда мог бы быть утилитой, тем более что свойств у него нет (сейчас посмотрел).
Но его делали в 96м году, а тогда сделали много глупостей: класс Date, интерфейс Cloneable итд.
Про это еще Блох писал)
Webkill 24.06.2010 13:08 # −1
если бы да кабы
а если программу попытаются запустить на девятитысячеядерном квантовом процессоре Марклар13 выпущенном на альдебаране??? там такая неопределённость будет, что миллион рантаймов одновременно - это ещё не предел. Давайте под это тоже заранее подстраиваться.
>Но его делали в 96м году, а тогда сделали много глупостей: класс Date, интерфейс Cloneable итд.
А что не так с ними?
Анонимус 24.06.2010 13:12 # 0
Вот присловутое "знание ооп" и помогает делать программы более гибкими, что бы их можно было изменять и рефакторить, а не переписывать с ноля))
Вы никогда не пытались поддерживать крупный проект в течение 5ти лет?
>>А что не так с ними?
Date mutable, и потому почти весь deprecated.
Умные программисты джава хранят дату в лонге)
Cloneable вообще интерфейс-маркер, почитайте как он работает. Глупо и нелогично
Webkill 24.06.2010 13:26 # −1
Date mutable, и потому почти весь deprecated.
Умные программисты джава хранят дату в лонге)
не додумались до классов по значению, как в шарпе, вот и страдают, дебилки
> Cloneable вообще интерфейс-маркер, почитайте как он работает. Глупо и нелогично
чем хоть он отличается от других интерфейсов?
Анонимус 24.06.2010 13:30 # 0
1) Не в шарпе, а в CLR.
2) Даже и без них все было бы хорошо -- буть Date неизменяем. Но чертово требование обратной совместимости((((
>>чем хоть он отличается от других интерфейсов?
У него нет методов. ни одного.
Если ты имплементишь его -- ты обязан оверрайтнуть метод clone.
Прост обязан, и все. Хотя метода clone у интерфейса нет
Webkill 24.06.2010 13:36 # −1
и там, и там.
> У него нет методов. ни одного.
понял. это интерфейсный костыль для эмуляции аннотаций, когда ихещё небыло, аха.
Анонимус 24.06.2010 13:38 # 0
Ну value-types все таки есть в платформе, а не в конкретном языке.
В vb.net они тоже есть.
>>это интерфейсный костыль для эмуляции
именно. называется "интерфейс-маркер"
Webkill 24.06.2010 13:43 # −2
поведение value types чётко прописане в стандарте сишарпа. и value types CLR'а отличаются от value types сишарпа немного.
так можно договориться до того, что в с++ как в языке нет переменных, они предоставляются платформой (в регистрах или в стеках)...
> называется "интерфейс-маркер"
ага, или самокат.
Анонимус 24.06.2010 13:47 # 0
можно пруфлинк?
>>ага, или самокат.
Вы нелюбите терминологию
Webkill 24.06.2010 04:19 # −3
хм, в яве имеем public void addShutdownHook(Thread hook) и ставить хек на уже гуляющий поток не имеет смысла...
не очень понял замысла.
энивейз, допустим если в фреймворке бы было просто addShutdownHook(FunctionProc); то если бы нужно было хранить для каждого треда бы просто сделал новый метод addShutdownHook(FunctionProc proc, Thread context) и всё. Хотя и это глупо, можно в addShutdownHook(FunctionProc); автоматически определять текущий поток.
Или я не так понял пример? Вообще хрень какая-то.
Анонимус 24.06.2010 13:08 # 0
Я моем примере пользователь не знал, что в логике используется тред.
А Вы предлагаете насильно передавать туда тред.
>> Хотя и это глупо, можно в addShutdownHook(FunctionProc); автоматически определять текущий поток.
И иметь Map<Поток, List<Хук>> ?:)))
Очень удобно.
Куда удобнее было бы иметь по объекту на поток.
Чем проще класс, чем он глупее -- тем легче его тестировать.
Я не понимаю: Вы сторонник процедурного подхода что ли?
Webkill 24.06.2010 13:11 # −2
Куда удобнее было бы иметь по объекту на поток.
Чем это неудобно?
> Я не понимаю: Вы сторонник процедурного подхода что ли?
смешанного ) не слишком ООП и не слишком процедурный шобэ
так скать, ООП это хорошо, однако не надо забывать, программа это как бы ещё в первую очередь императив вокруг объектов, а не объекты и где-то там может быть на 2 часа работы останется императив
Анонимус 24.06.2010 13:15 # 0
В моем примере объект знает только про свои данные, про потоки он вообще ничего не знает.
В вашем -- класс знает про потоки.
В моем решении классы более узкозаточенные, более тупые, и потому они легче и их проще тестировать и поддерживать.
Почитайте про cohesion.
Говногость 23.06.2010 19:00 # 0
Внутри этого конструктора ожидается завершение потока и получения из него результата.
Webkill 23.06.2010 18:21 # −9
threadRAII - как крута!