Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> static, время жизни? 
:(
    Опции темы
bel_nikita
  Дата 31.5.2004, 08:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Корректен ли такой код:
Цитата

MyClass* Function()
{
    static MyClass TestClass;
    return &TestClass;
}



--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
AndyY
Дата 31.5.2004, 08:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 316
Регистрация: 8.5.2004
Где: СПб

Репутация: 2
Всего: 4



корректен. учитывай, что конструктор вызовется при первом обращении к функции.


--------------------
PM MAIL WWW   Вверх
bel_nikita
Дата 31.5.2004, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Но если деструктор MyClass сделать приватным, то компилятор ругается.
Почему?


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
AndyY
Дата 31.5.2004, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 316
Регистрация: 8.5.2004
Где: СПб

Репутация: 2
Всего: 4



потому что Function - не имеет доступа к приватным мемберам.
а зачем его делать приватным?


--------------------
PM MAIL WWW   Вверх
bel_nikita
Дата 31.5.2004, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Ага, тогда почему идет обращение к деструктору????


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
AndyY
Дата 31.5.2004, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 316
Регистрация: 8.5.2004
Где: СПб

Репутация: 2
Всего: 4



при выгрузке модуля (например, завершении проги) вызываются деструкторы у всех статических объектов (у которых были вызваны конструкторыsmile.gif). Вот только порядок вызова ничем не определен, что ставит под вопрос возможноcть использования этих объектов.


--------------------
PM MAIL WWW   Вверх
bel_nikita
Дата 31.5.2004, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Да, но функция является дружественной классу и конструктор у меня в приватах.
Идея такова, что доступ к классу имеет одна функция. Типа Singleton.
Лучше приведу пример (наверное много глупостейsmile.gif, но это чисто тестовая конструкция):
Код
 template<typename T>
   void InitDispatch()
 {
   typedef cDispatcher<T> Dispatcher;
   static Dispatcher Dispatch;
   Dispatcher::m_Dispatcher=&Dispatch;
   //static HANDLE hMutex;
 }

 template<typename T>
   void DeInitDispatch()
 {
   typedef cDispatcher<T> Dispatcher;
 }

 template<typename T>
   class cDispatcher
   {
   typedef cQueue<T> Queue;
   typedef cDispatcher*  PDispatcher;
   friend void InitDispatch();
   friend void DeInitDispatch();
   public:
     ~cDispatcher() { cDispatcher::m_Dispatcher=NULL; } // Почему деструктор в пабликах должен быть???
    inline static cDispatcher* Instance() { return cDispatcher::m_Dispatcher; }
    void Dispatch()
    {
      printf("\nDispatch");
    };

   protected:
   private:
     cDispatcher(){};
     cDispatcher(const cDispatcher&);
     static cDispatcher*  m_Dispatcher;
     Queue m_Queue;
   };

 template<typename T>
   cDispatcher<T>::PDispatcher cDispatcher<T>::m_Dispatcher=NULL;



--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
Nastya
Дата 31.5.2004, 17:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 27.3.2002
Где: Мариуполь

Репутация: 5
Всего: 44



Цитата
(наверное много глупостей, но это чисто тестовая конструкция):


Да глупостей много, начиная уже с первых двух строк

template<typename T>
void InitDispatch()
{
}

А что кроме как делать private деструктор выхода из ситуации нет?
Може там где ты объявляешь дружественную функцию, и где функцию описываешь разные прототипы в этом легко напортачить особенно с шаблонами?



--------------------
Что бы понять рекурсию, надо понять рекурсию

"Профессионал - это человек сделавший все возможные ошибки в очень узкой области". Н.Бор
PM MAIL   Вверх
achmed
Дата 31.5.2004, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 150
Регистрация: 12.4.2004

Репутация: нет
Всего: нет



Цитата(AndyY @ 31.5.2004, 15:52)
при выгрузке модуля (например, завершении проги) вызываются деструкторы у всех статических объектов (у которых были вызваны конструкторыsmile.gif). Вот только порядок вызова ничем не определен, что ставит под вопрос возможноcть использования этих объектов.

правило в C++: последним создан, первым уничтожен.

Добавлено @ 18:36
элегантный шаблон Singletone (вроде предложен Майерсом, может я ошибаюсь)
template <class T>
T * Singletone()
{
static T s;
return &S;
}

Это сообщение отредактировал(а) achmed - 1.6.2004, 13:25
PM MAIL   Вверх
AndyY
Дата 1.6.2004, 08:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 316
Регистрация: 8.5.2004
Где: СПб

Репутация: 2
Всего: 4



achmed
правило прописано в стандарте? IMHO это просто конкретная реализация CRT (статические объекты складываются в какой-то список).
один фиг юзать невозможно, поскольку никто не знает последовательность создания. Да и удобство сомнительное.

btw а почему не сделать деструктор protected?

и еще вопрос на грани офтопика - зачем столько кода, который не делает ничего? неужели он хоть раз помог кому-то помог избежать ошибки?


--------------------
PM MAIL WWW   Вверх
bel_nikita
Дата 1.6.2004, 09:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Nastya
Цитата
Да глупостей много, начиная уже с первых двух строк

template<typename T>
void InitDispatch()
{
}

А что глупого в этих строчках? rolleyes.gif
Цитата

template<typename T>
void InitDispatch()
{
  typedef cDispatcher<T> Dispatcher;
  static Dispatcher Dispatch;
  Dispatcher::m_Dispatcher=&Dispatch;
}

Обясните пожалуйста. Не вижу ничего странного в строчке template<typename T> void InitDispatch()

Цитата
зачем столько кода, который не делает ничего? неужели он хоть раз помог кому-то помог избежать ошибки?

Это хочу настраиваемый диспетчер сообщений забомбить smile.gif


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
AndyY
Дата 1.6.2004, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 316
Регистрация: 8.5.2004
Где: СПб

Репутация: 2
Всего: 4



bel_nikita
А что такое диспатчер сообщенийsmile.gif? Могучий фильтр на DispatchMessage:)) или NotifyController наподобии java?

Все-же не пойму, зачем так сложно.
кстати, приведу пример - как сделано у меня:

Код

template <class _class>
class _static_pointer_t
{
public:
   _static_pointer_t()
   {  
 _assert( static_ptr() == 0 );
 static_ptr() = (_class*)this;    
}
   ~_static_pointer_t()
   {        static_ptr() = 0;    }
public:
   static _class  *&static_ptr()
   {static _class  *pclass = 0;return pclass;}
};

class module : public _static_pointer_t<module>
...



и обращаешься:
module *p = module::static_ptr();
...

это конечно далеко от совершенства, но ситуаций с ошибкой в коде связанной с этой конструкцией не было. зачем делать больше?









--------------------
PM MAIL WWW   Вверх
bel_nikita
Дата 1.6.2004, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Цитата
А что такое диспатчер сообщений?

В проге есть различные объекты. У каждого свой тип (TypeObject) и идентификационный номер (ID). И все объекты должны обмениваться сообщениями между собой. Т.е. есть некий виртуальный базовый класс с функцией, типа ProcessMessage(Message). А диспетчер должен управлять сообщениями. То бишь есть глобальная очередь сообщений, куда все объекты, производные от базового, складывают свои события. Диспетчер фильтрует, например в отдельном треде, сообщения и вызывает виртуальную функцию ProcessMessage(Message) для объекта, которому предназначено данное сообщение.
Вот, такая вот не хитрая конструкцияsmile.gif
Че-та написал, не знаю, понятно ли? rolleyes.gif


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
AndyY
Дата 1.6.2004, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 316
Регистрация: 8.5.2004
Где: СПб

Репутация: 2
Всего: 4



bel_nikita
интересная задача.
тред я пожалуй не стал бы пускать - тормозить будет. или он или интерфейс... А вот обработчики в разных тредах - есть над чем подумать.
а почему базовый класс виртуальный?

и зачем вообще вся тема с синглетоном - ведь понятно, что диспатчер один...
а если он не один будет - грубо говоря в другом окне потребуется другая чехарда с объектами? обломс с синглетоном.


--------------------
PM MAIL WWW   Вверх
bel_nikita
Дата 1.6.2004, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Цитата
а почему базовый класс виртуальный?

Не правильно изложил мысльsmile.gif. Не виртуальный, а абстрактный.
Цитата
и зачем вообще вся тема с синглетоном - ведь понятно, что диспатчер один...

Да, он должен быть один, но не хочется привязываться к конкретному типу сообщения. Типа, чтоб была сразу библиотека готовая и настраиваемая. Чтобы можно было без труда в другой проект перенести.
Но если делать дипетчер через шаблон, то можно в проге два диспечера сделать с различными типами сообщений и базовыми объектами. Но это так из области фантастикиsmile.gif

Еще вот,что: я не под WIN32 сижу. Так, что окна мне не страшныsmile.gif

Вот, приведу еще пример базового класса:
Код
 template<typename T> class cDispatcher;
 /************************************************************************/
 /* class cBase                                                          */
 /************************************************************************/
 template<typename Message, class TypeObject=DWORD, class IdObject=DWORD>
   class cBase
   {
     typedef std::pair<TypeObject,IdObject> PAIR;
     typedef cBase<Message>*  PBASE;
     friend class cDispatcher;
   public:
     typedef std::map<PAIR,PBASE> MAP;

                 cBase(const TypeObject& TypeObj, const IdObject& IdObj);
     virtual ~   cBase();
     TypeObject  GetType() const { return m_ID.first; }
     IdObject    GetID() const { return m_ID.second; }
     //virtual BOOL  ProcessMessage(const Message&)=0;
     
   protected:
     PAIR m_ID;
   private:
     static MAP  m_staticMap;
   };

 template<typename Message, class TypeObject, class IdObject>
   cBase<Message, TypeObject, IdObject>::MAP
   cBase<Message, TypeObject, IdObject>::m_staticMap;

 /*
  * CONSTRUCTOR
  */
 template<typename Message, class TypeObject, class IdObject>
   cBase<Message, TypeObject, IdObject>::
   cBase(const TypeObject& TypeObj, const IdObject& IdObj)
 {
   PAIR Temp=std::make_pair(TypeObj,IdObj);
   m_staticMap.end();
   if ( cBase::m_staticMap.find(Temp) != cBase::m_staticMap.end() )  // ELEM EXIST
   {
     //std::out_of_range("Elem exist");
   }
   else
     cBase::m_staticMap.insert( MAP::value_type(m_ID=Temp, this) );
 }

 /*
  * DESTRUCTOR
  */
 template<typename Message, class TypeObject, class IdObject>
   cBase<Message, TypeObject, IdObject>::~cBase()
 {
   MAP::iterator i=cBase::m_staticMap.find(m_ID);
   if ( i != cBase::m_staticMap.end() )                             // ELEM EXIST
     cBase::m_staticMap.erase(i);
   else
     throw ("BRED");
 }

Мысля такова:
Если создается объект, производный от базового класса, то поитер заносится в статический МАР. А когда диспетчер имеет сообщение, то он бежит по этому МАРу и отыскивает нужный объект(т.е. которому предназначено сообщение) и вызывает виртуальный метод ProcessMessage(const Message&).
А если объект, производный от базового, удаляется, то базовый деструктор удаляет свой поитер из МАР. Т.е. можно динамически создавать и удалять объекты в процессе работы проги. И все они могут свободно обмениваться событиями между собой.
Вроде так rolleyes.gif
Но, вот подумал. А если этих объектов пару тысяц будет? Долго искать придетсяsmile.gif

Это сообщение отредактировал(а) bel_nikita - 1.6.2004, 13:20


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
mr.DUDA
Дата 1.6.2004, 13:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



Цитата
когда диспетчер имеет сообщение, то он бежит по этому МАРу и отыскивает нужный объект(т.е. которому предназначено сообщение) и вызывает виртуальный метод ProcessMessage(const Message&).
А если объект, производный от базового, удаляется, то базовый деструктор удаляет свой поитер из МАР.

А если будет вот такая ситуация: диспетчер сообщений вызвал в своём треде ProcessMessage объекта A, но в процессе обработки мессаги объект A (в другом треде) вдруг прекратил своё существование (вызов деструктора, удаление пойнтера из MAP), то что тогда ? По идее, упасть должно wink.gif


--------------------
user posted image
PM MAIL WWW   Вверх
bel_nikita
Дата 1.6.2004, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Цитата
А если будет вот такая ситуация: диспетчер сообщений вызвал в своём треде ProcessMessage объекта A, но в процессе обработки мессаги объект A (в другом треде) вдруг прекратил своё существование (вызов деструктора, удаление пойнтера из MAP), то что тогда ? По идее, упасть должно 

wow.gif Ага, точно. Критичная ситуация withstupid.gif
Но синхронизация на что? Блокируем доступ к разделяемым ресурсам на время вызова ProcessMessage и изменения в МАРе.
А если диспетчер иммет мессагу, но этого объекта уже нет, то зачем это сообщение? Удаляем его из очереди....
Тут надо подумать... cool.gif

Это сообщение отредактировал(а) bel_nikita - 1.6.2004, 14:17


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
AndyY
Дата 1.6.2004, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 316
Регистрация: 8.5.2004
Где: СПб

Репутация: 2
Всего: 4



2000 для нормальной мапы - пустяки, максимальный путь поиска - 11 сравнений (2048 элементов)
только вот криво это - если 2000 объектам нужно как-то реагировать на событие. Вот если 1-2 объекта - это понятно... А объекты одного типа лучше обрабатывать вместе (забавно посмотреть как реализован механизм нотификации через IConnectionPoint у микрософтов.

еще раз вернусь к вопросу - нафига все-же синглетон? тем более с неочевидным синтаксисом.
я считаю что если что-то можно написать просто и понятно, мудрить тут не стоит - потеряешь время сначала на красоту, а потом на лишние глюки. автор stl похоже со мной не согласенsmile.gif))


--------------------
PM MAIL WWW   Вверх
bel_nikita
Дата 1.6.2004, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Цитата
еще раз вернусь к вопросу - нафига все-же синглетон? тем более с неочевидным синтаксисом.

Какие предложения есть? Через new... как-то не катит. Сделать все методы диспетчера статическими?...В принципе так и делаю
Цитата
А объекты одного типа лучше обрабатывать вместе

А это как? Не понял? withstupid.gif Можно по-подробнее.

А по мне дык STLport - rulezzz notify.gif


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
AndyY
Дата 1.6.2004, 19:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 316
Регистрация: 8.5.2004
Где: СПб

Репутация: 2
Всего: 4



Как? ну, самое простое, в хидере:


class dispatcher
{
///методы
};
extern dispatcher g_disp;

в .cpp:
dispatcher g_disp;

и все!

про обработку:
например, у тебя 1000 объектов, которые нужно перерисовать (у них изменилось общее свойство). разумнее их перерисовать все скопом специализированной функцией, чем по одному (как минимум экономия на вызове виртуальной функции). Зачастую и алгоритм оптимизировать - например в windows 1000 вызовов Invalidate/UpdateWindow выполнятся намного медленней, чем для 1. В общем наличие большого числа листенеров сообщений - повод их объеденить в спец. менеджер, который и будет обрабатывать события для всех объектов вместе.


--------------------
PM MAIL WWW   Вверх
mr.DUDA
Дата 1.6.2004, 23:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



Подсказка: у 20-ти объектов одного и того же базового класса, скорее всего будет 20 однотипных обработчиков сообщений. Так что можно вместо внешнего класса сделать внутренний класс CMessageDispatcher, который будет обеспечивать обработку мессаг для всех классов, производных от данного (т.е. хранить MAP, вызывать ProcessMessage и т.п.).

Для генерации сообщения достаточно будет вызвать метод FireMessage любого объекта. Данный метод вызовет ProcessMessage объекта, и т.п. Реализация будет зависеть от реализации вирт. ф-ции FireMessage объекта (которая может делать всё что угодно - от простого вызова ProcessMessage данного объекта, до перебора всех элементов MAP данного объекта).

Идея, в общем-то простая. У каждого объекта есть набор однотипных свойств, поэтому есть набор однотипных событий, значит такие объекты могут быть объединены в один MAP обработки событий.......


--------------------
user posted image
PM MAIL WWW   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0718 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.