AlexCasual
Помогающий
Offline
|
|
« : 10-11-2011 14:46 » |
|
Есть базовый класс CObject,от него наследуется singletone-класс CChild. Задача : - как сделать так,чтобы при помощи CObject можно было просигнализировать клиентам CChild о наступлении какого-либо события?
Т.е. имеется объект класса CObject,он отслеживает некоторые события,о которых должны знать клиенты CChild.
Подскажите способ реализации...при помощи static членов CObject или callback-ов?
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #1 : 10-11-2011 15:37 » |
|
Подскажите способ реализации...при помощи static членов CObject или callback-ов?
Не "или" - "и".
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #2 : 10-11-2011 16:02 » |
|
А причём тут CObject? Отношение между CChild и его клиентами - это структурное отношение. Не "или" - "и". (Подумав.) Да.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
|
RXL
|
|
« Ответ #4 : 11-11-2011 06:25 » |
|
AlexCasual, в CObject должны быть реализованы: 1. Регистрация и разрегистрация любого числа callback. 2. Механизм генерации событий. 3. Диспетчер событий, распространяющий п.2 согласно п.1.
Больше ничего по тому, что ты написал сказать не могу. Слишком поверхностно.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
AlexCasual
Помогающий
Offline
|
|
« Ответ #5 : 11-11-2011 06:56 » |
|
RXL,огромное спасибо!
При помощи объектов CObject - проверяется размер файла на диске и если он меньше определённого размера об этом должны узнать клиенты CChild и удалить данный файл.
RXL,а можно немного подробнее?)
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #6 : 11-11-2011 07:08 » |
|
AlexCasual, сперва ты расскажи подробнее, чтобы мы знали, на что тратим свое время. Пока похоже, что ты не совсем представляешь себе задачу, ее цели и пути реализации.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
AlexCasual
Помогающий
Offline
|
|
« Ответ #7 : 11-11-2011 11:06 » |
|
RXL,грубо говоря объект класса CObject должен просигнализировать(установить переменную?) о том,что размер файла меньше заданного,а singletone CChild подхватить и обработать данную ситуацию. Если на CObject возлагается регистрация и разрегистрация коллбэка,то какие действия должен выполнить CChild?
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #8 : 11-11-2011 11:36 » |
|
Я не заметил, чем последний пост отличается от первого. Не придумывай сложностей заранее - они сами добавятся в процессе разработки.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #9 : 11-11-2011 13:36 » |
|
Если человек знает, что такое "одиночка", то наверно должен знать и про "наблюдатель".
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
AlexCasual
Помогающий
Offline
|
|
« Ответ #10 : 12-11-2011 19:12 » |
|
Если использовать паттерн Observer,то меня смущает такой момент : ведь CChild наследуется как singletone от CObject,поэтому CObject ничего не может знать о классе CChild и хранение ссылок на CChild в CObject - нарушение наследования?Ко всему CChild - singletone...Или я что-то не понимаю?
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #11 : 12-11-2011 21:13 » |
|
AlexCasual, ты не то не понимаешь, ты вообще бредишь.
Во-первых, "одиночка" и наследование - вещи между собой несовместимые (из-за закрытия конструкторов одиночки), а потому между собой не связанные. Поэтому фраза "наследуется как singletone" - это какая-то ерунда. Либо сперва наследуется, а потом уже становится одиночкой, либо никак, потому что одиночка не наследуется из-за закрытых конструкторов.
Во-вторых, да, конечно, предок не имеет информации о потомках (и не надо ему её иметь).
В-третьих внутри предка можно хранить ссылки на объекты классов-потомков без раскрытия информации о классах-потомках. Это самый обыкновенный полиморфизм, и проблем тут никаких нет. Предку достаточно знать свой собственный класс (и он сам себя знает), чтобы работать с экземплярами всей своей иерархии.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
AlexCasual
Помогающий
Offline
|
|
« Ответ #12 : 13-11-2011 08:56 » |
|
Либо сперва наследуется, а потом уже становится одиночкой ...так и есть.
|
|
|
Записан
|
|
|
|
AlexCasual
Помогающий
Offline
|
|
« Ответ #13 : 13-11-2011 10:31 » |
|
Вот набыдлил такой вариант : observer.h#include <windows.h>
class CObject { public: CObject() {}; ~CObject() {};
public:
virtual void update() {};
void static add_reference(CObject* ref) { m_observer = ref; }
void static remove_reference(CObject* ref) { }
public: void static _notify() { m_observer->update(); }
private: static CObject* m_observer; };
class CChild: public CObject { private: CChild() :CObject() {};
public: ~CChild();
public: virtual void update() { if(m_refresh == false) { m_refresh = true; } }
bool is_refresh() { if(m_refresh) { MessageBoxA(NULL,"lalala","llll",1); } return m_refresh; }
public: static CChild* Instance() { if (!m_pInstance) m_pInstance = new CChild; return m_pInstance; } private: bool m_refresh; static CChild* m_pInstance; };
test.cpp#include "observer.h"
CObject* CObject::m_observer = NULL;
CChild* CChild::m_pInstance = NULL;
int main(int argc, char* argv[]) { CObject cobjct;
CChild::Instance()->add_reference(CChild::Instance()); cobjct._notify(); bool res = CChild::Instance()->is_refresh();
return 0; }
Правильно ли я уловил идею?
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #14 : 13-11-2011 15:05 » |
|
AlexCasual, для наблюдателя static не нужны в общем случае. Идея непонятна.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
AlexCasual
Помогающий
Offline
|
|
« Ответ #15 : 14-11-2011 06:47 » |
|
для наблюдателя static не нужны в общем случае. Идея непонятна. Но,например,я создаю 10ть объектов CObject,а singleton CChild имеет один экземпляр...как в этом случае узнать,от какого именно CObject пришло уведомление? Если убрать static - идея будет понятна?
|
|
« Последнее редактирование: 14-11-2011 07:03 от AlexCasual »
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #16 : 14-11-2011 07:25 » |
|
AlexCasual, начинать надо с замысла.
Ты сам сказал, что утебя есть 1 родительский класс и несколько потомков-одиночек.
Каждый экземпляр одиночки есть независимый экземпляр предка, сам предоставляет всем окружающим возможность подписаться на его события потому, что предок реализует наблюдателя.
А вот что ты наворотить хочешь, остаётся непонятным. Если "доску объявлений", то причём тут вообще наследование? Это всё решается через структурные отношения между 1 экземпляром "доски" и многими экземплярами её пользователей, которые на ней вывешивают объявления (или флаги событий) и читают с неё. В доске при желании можно реализовать наблюдателя.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
AlexCasual
Помогающий
Offline
|
|
« Ответ #17 : 14-11-2011 09:43 » |
|
Ещё раз...
Есть объект класса CObject, есть объект класса CChild (singletone ::Instance())...объект CObject должен оповестить объект CChild о наступлении какого-либо события...
"Фабрики" и "доски" здесь не при чём...
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #18 : 14-11-2011 11:03 » |
|
AlexCasual, попробуй, всё-таки, описать саму задачу, а не техническую проблему. Тут никто не понимает, чего ты хочешь добиться своей конструкцией. То есть, не описывай "как" - опиши, что ты пытаешься сделать. Не технически, а по смыслу.
|
|
|
Записан
|
|
|
|
AlexCasual
Помогающий
Offline
|
|
« Ответ #19 : 18-11-2011 10:31 » |
|
Вад,задача банальна - у меня есть огромный кусок кода,который писал не я,мне необходимо дописать функционала немного на основании уже созданных классов...Поэтому я формулирую задачу так,как сам её и понимаю... Попробую ещё раз - есть общий интерфейс класса CObject,в одном потоке создаётся объект данного класса obj_1,с помощью его производятся некоторые манипуляции,а во втором потоке происходит работа с singleton'ом CChild,который должен произвести некоторые действия по событию от obj_1...Как смог...
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #20 : 18-11-2011 10:52 » |
|
Попробуем отделить твою задачу от того, что уже написано другими. Во-первых, я для себя переформулировал происходящее, в моём понимании. Есть некий тип, мы создаём экземпляр этого типа, чтобы выполнять над ним некоторые полезные действия. При этом, во втором потоке мы хотим получать уведомления о событиях, происходящих в результате наших действий. Так? Теперь, где чьё: полезные действия уже реализованы до тебя в этом CObject, или ты пытаешься сам обернуть это всё в собственноручную конструкцию? Аналогично с синглетоном - он твой, или это уже относится к чужому коду? В чём состоит твоя персональная задача по "дописыванию функционала"? Примеры формулировки задач: "сделать свою реализацию _полезных_действий_", "добавить в код CObject механизм уведомления о событиях", и т.п. Просто, пока всё ещё непонятно, что же это за кусок кода, какие ограничения накладываются этим куском, что нужно поменять в этом куске, и как ты себе видишь эти изменения. Вот это я и называю описанием задачи. При этом, в детали по поводу чужого кода вдаваться не обязательно, если это коммерческая информация Но ограничения и необходимые действия осознать и описать надо обязательно - без этого мотивация конкретных практических действий не ясна совершенно.
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #21 : 18-11-2011 10:52 » |
|
AlexCasual, ты не понимаешь, что такое описание задачи. Надо понять в общих чертах, что и зачем делает тот большой кусок кода. Только после этого ты сможешь что-то расширить и вмешаться в работу этого большого куска так, чтобы при этом ничего не развалилось. "Создаётся объект", "с его помощью производятся манипуляции" и т.д. - это не описание задачи, а описание имеющегося решения не понять чего. а во втором потоке происходит работа с singleton'ом CChild,который должен произвести некоторые действия по событию от obj_1... Так "наблюдатель" не обеспечивает работу в разных потоках. Если ты вызываешь обработчик события из CObject, то этот обработчик работает в этом же потоке. Тогда схема вообще другая, нужно объекты синхронизации использовать, флаги Event или что-то в этом духе.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
AlexCasual
Помогающий
Offline
|
|
« Ответ #22 : 18-11-2011 15:52 » |
|
Вад,да.ты всё совершенно верно понял.
Мне необходимо "добавить в код CObject механизм уведомления о событиях".
Потоки это частный случай,методы пассивного/активного ожидания не интересуют...
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #23 : 18-11-2011 17:25 » |
|
AlexCasual, это у тебя в соседней теме.
Напиши и отработай прототип, затем перенесёшь идею реализации в основной код.
Вот у тебя классы: A - подписывает и отписывает подписчиков на события, сообщает подписчикам о событии путём вызова их сигнального метода; и B - подписчик с сигнальным методом.
Вот возьми и напиши чистое решение в один файл. Вопрос 10-20 строчек.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
|