Re[3]: Велосипед
От: Celestial Россия http://video.google.com/googleplayer.swf?docId=1055185227485133586
Дата: 21.12.06 10:41
Оценка:
Мне бы тоже очень пригодился бы ваш вариант
если можно на infernal-demon[собака]mail.ru
Спасибо !
Re: Делегаты на C++
От: Smooky Россия  
Дата: 22.12.06 09:18
Оценка:
Здравствуйте, Александр Шаргин, Вы писали:

АШ>Статья :

АШ>Делегаты на C++
Автор(ы): Александр Шаргин
Дата: 19.03.2003
Делегаты в CLR удобны, типобезопасны и эффективны. Последнее время на форумах RSDN часто поднимается вопрос о том, можно ли реализовать делегаты с аналогичными свойствами, оставаясь в рамках "чистого" C++. Оказывается, это вполне возможно. В этой статье я покажу, как это сделать.


АШ>Авторы :

АШ>Александр Шаргин

АШ>Аннотация :

АШ>Делегаты в CLR удобны, типобезопасны и эффективны. Последнее время на форумах RSDN часто поднимается вопрос о том, можно ли реализовать делегаты с аналогичными свойствами, оставаясь в рамках "чистого" C++. Оказывается, это вполне возможно. В этой статье я покажу, как это сделать.

Было бы неплохо всё-таки разжевать еще, как на своих аллокаторах это сделать, всё таки предоставлять читателю, скажем так, не совсем тривиальную задачу, как-то незакончено... Статья понравилась! Просто чес слова, извините за грубость, ну задолбали с этим БУСТОМ...! Да ОЧЕНЬ много, очень много кто НЕ пользует его по многим объективным причинам. Да и собсна из тех кто пользует, толком никто и незнает, как там всё устроено...
Только Путин, и никого кроме Путина! О Великий и Могучий Путин — царь на веки веков, навсегда!
Смотрю только Соловьева и Михеева, для меня это самые авторитетные эксперты.
КРЫМ НАШ! СКОРО И ВСЯ УКРАИНА БУДЕТ НАШЕЙ!
Re: Делегаты на C++
От: mikhail.reload Россия  
Дата: 25.01.08 19:19
Оценка:
Здравствуйте, Александр Шаргин, Вы писали:

АШ>Статья :

АШ>Делегаты на C++
Автор(ы): Александр Шаргин
Дата: 19.03.2003
Делегаты в CLR удобны, типобезопасны и эффективны. Последнее время на форумах RSDN часто поднимается вопрос о том, можно ли реализовать делегаты с аналогичными свойствами, оставаясь в рамках "чистого" C++. Оказывается, это вполне возможно. В этой статье я покажу, как это сделать.


АШ>Авторы :

АШ>Александр Шаргин

АШ>Аннотация :

АШ>Делегаты в CLR удобны, типобезопасны и эффективны. Последнее время на форумах RSDN часто поднимается вопрос о том, можно ли реализовать делегаты с аналогичными свойствами, оставаясь в рамках "чистого" C++. Оказывается, это вполне возможно. В этой статье я покажу, как это сделать.




Я немного "обжегся", не посомтрев на реализацию. Используется dynamic_cast

C_METHOD_DELEGATE<TObj, TRet TEMPLATE_ARGS>* pMethodDel =
dynamic_cast<C_METHOD_DELEGATE<TObj, TRet TEMPLATE_ARGS>* >(pDelegate);

так чтo,народ, проверьте ключ компиляции /GR. Если он не стоит — будет генериться исключение. В моем случае оно лихо ловилось, а объект из списка не удалялся.

А вообще — спасибо автору.
Re: Делегаты на C++
От: my_soul  
Дата: 04.08.08 08:34
Оценка:
Добрый день!
Подскажите, как это работает

Вот у вас есть определение:

template <class TObj, class TRet TEMPLATE_PARAMS>
I_DELEGATE<TRet TEMPLATE_ARGS>* NewDelegate(TObj* pObj, TRet (TObj::*pMethod)(PARAMS))
{
  return new C_METHOD_DELEGATE<TObj, TRet TEMPLATE_ARGS> (pObj, pMethod);
}


По моей логике, чтобы это хотябы скомпилировалось, надо передать в шаблон тип класса, метод которого
передается в делеат.
NewDelegate<CMyClass, и т.д.>(pMyClass, &CMyClass::Method);

Однако, этого не требуется. Как такого вы достигли?
Re[2]: Делегаты на C++
От: Юрий Жмеренецкий ICQ 380412032
Дата: 04.08.08 11:40
Оценка:
Здравствуйте, my_soul, Вы писали:

_>Добрый день!

_>Подскажите, как это работает

_>Вот у вас есть определение:


_>
_>template <class TObj, class TRet TEMPLATE_PARAMS>
_>I_DELEGATE<TRet TEMPLATE_ARGS>* NewDelegate(TObj* pObj, TRet (TObj::*pMethod)(PARAMS))
_>{
_>  return new C_METHOD_DELEGATE<TObj, TRet TEMPLATE_ARGS>(pObj, pMethod);
_>}
_>


_>По моей логике, чтобы это хотябы скомпилировалось, надо передать в шаблон тип класса, метод которого

_>передается в делеат.
_>NewDelegate<CMyClass, и т.д.>(pMyClass, &CMyClass::Method);

_>Однако, этого не требуется. Как такого вы достигли?

В случае шаблона функции(NewDelegate) это не обязательно, в отличии от шаблонного класса(C_METHOD_DELEGATE). Типы будут выведены исходя из фактических типов переданных аргументов. Собственно эта функция и нужна для того, чтобы при создании объекта класса C_METHOD_DELEGATE не приходилось указывать явно его параметры.
Re[3]: Делегаты на C++
От: my_soul  
Дата: 04.08.08 12:33
Оценка:
Здравствуйте, Юрий Жмеренецкий, Вы писали:

ЮЖ>В случае шаблона функции(NewDelegate) это не обязательно, в отличии от шаблонного класса(C_METHOD_DELEGATE). Типы будут выведены исходя из фактических типов переданных аргументов. Собственно эта функция и нужна для того, чтобы при создании объекта класса C_METHOD_DELEGATE не приходилось указывать явно его параметры.



Я тогда не понимаю:

NewDelegate(&obj, &CMyClass::func);



CMethodDelegate0 del(&obj, &CMyClass::func);


Почему для функции компилятор догадывается какой тип надо подставить в шаблон, а для класса нет?..
Re[4]: Делегаты на C++
От: Юрий Жмеренецкий ICQ 380412032
Дата: 04.08.08 13:20
Оценка: 2 (1)
Здравствуйте, my_soul, Вы писали:

_>Я тогда не понимаю:


_>
_>NewDelegate(&obj, &CMyClass::func);
_>



_>
_>CMethodDelegate0 del(&obj, &CMyClass::func);
_>


_>Почему для функции компилятор догадывается какой тип надо подставить в шаблон, а для класса нет?..


Первая конструкция — это выражение(expression), а второй — определение объекта типа CMethodDelegate0. Как мы можем определить объект неизвестного типа ?

Кроме того, возможны ситуации с шаблонным конструктором:

template<class>
struct A
{
  template<class t>
  A(t){}
};
//...
A a(1); // Какой здесь тип у a ?
Re[5]: Делегаты на C++
От: my_soul  
Дата: 04.08.08 13:29
Оценка:
Здравствуйте, Юрий Жмеренецкий, Вы писали:

ЮЖ>Первая конструкция — это выражение(expression), а второй — определение объекта типа CMethodDelegate0. Как мы можем определить объект неизвестного типа ?


ЮЖ>Кроме того, возможны ситуации с шаблонным конструктором:


ЮЖ>
ЮЖ>template<class>
ЮЖ>struct A
ЮЖ>{
ЮЖ>  template<class t>
ЮЖ>  A(t){}
ЮЖ>};
ЮЖ>//...
ЮЖ>A a(1); // Какой здесь тип у a ?
ЮЖ>




Ясно! Спасибо!
Re: Делегаты на C++
От: Anton_86 Украина  
Дата: 25.11.08 15:41
Оценка:
Здравствуйте, Александр Шаргин, Вы писали:

К сожалению данный код не работает корректно в VS2008:

Ваш код:

for(it = m_DelegateList.begin(); it != --m_DelegateList.end(); ++it)
       static_cast<IDelegate*> (*it)->Invoke(ARGS);


Мне пришлось поменять на


if ( !m_DelegateList.empty() )
{
    for(it = m_DelegateList.begin(); it != --m_DelegateList.end(); ++it)
       static_cast<IDelegate*> (*it)->Invoke(ARGS);
}


так как рантайм VS2008 выбрасывает исключение нарушения границ доступа при попытке декрементировать итератор который возвращен методом end().
Best Regards. Anton.
Re: "в языке C++ операторы не наследуются (?)"
От: Аноним  
Дата: 25.11.08 18:29
Оценка:
Раз уж подняли эту тему, такой вопрос:

Насторожила фраза в статье: "Дело в том, что в языке C++ операторы не наследуются."
Попробовал на VC++2005 — наследуются. И в Стандарте не нашёл подтверждения обратному.
Буду благодарен за пояснения особенностей наследования операторов в С++.

Заранее спасибо.

PS
По ходу чтения возникла мысль: не проще ли генерировать классы на каком-либо скрипте?
Re[2]: "в языке C++ операторы не наследуются (?)"
От: johny5 Новая Зеландия
Дата: 26.11.08 00:24
Оценка:
А>PS
А> По ходу чтения возникла мысль: не проще ли генерировать классы на каком-либо скрипте?

Кстати, не знает ли кто простой и проверенный способ в студии по описанию класса генерить операторы ==, !=, =; конструктор по умолчанию, копирования, макросы сериализации (тут ессно нуно ручками будет что то в чём то прописать), и прочий мегатонный мусор. Плюс стандартные #ifndef BLABLABLA_H_INCL__ мусор ___ #define BLABLABLA_H_INCL__ мусор ___ и #include в .cpp файле.

Чтоб вот нажал кнопку, бах и всё на месте..
Желательно было б конечно в идеале уметь обновлять все эти структуры при обновлении полей.

Или хотя бы макрос, который оформлял бы дефиницию функции в cpp по её декларации в классе в h, т.е.

.h файл
class A
{
  virtual int method(const Type& .. ) const;
  ..
};


в

.cpp файл
int A::method(const Type& .. ) const
{
}
Re[3]: "в языке C++ операторы не наследуются (?)"
От: eHomo  
Дата: 26.11.08 09:51
Оценка: +1
Здравствуйте, johny5, Вы писали:

А>>PS

А>> По ходу чтения возникла мысль: не проще ли генерировать классы на каком-либо скрипте?

J>Кстати, не знает ли кто простой и проверенный способ в студии по описанию класса генерить операторы ==, !=, =; конструктор по умолчанию, копирования, макросы сериализации (тут ессно нуно ручками будет что то в чём то прописать), и прочий мегатонный мусор. Плюс стандартные #ifndef BLABLABLA_H_INCL__ мусор ___ #define BLABLABLA_H_INCL__ мусор ___ и #include в .cpp файле.


J>Чтоб вот нажал кнопку, бах и всё на месте..

J>Желательно было б конечно в идеале уметь обновлять все эти структуры при обновлении полей.

J>Или хотя бы макрос, который оформлял бы дефиницию функции в cpp по её декларации в классе в h, т.е.


J>.h файл

J>
J>class A
J>{
J>  virtual int method(const Type& .. ) const;
J>  ..
J>};
J>


J>в


J>.cpp файл

J>
J>int A::method(const Type& .. ) const
J>{
J>}
J>


Visual Assist
Re[2]: Делегаты на C++
От: Кодт Россия  
Дата: 26.11.08 10:56
Оценка:
Здравствуйте, Anton_86, Вы писали:

<>
Вообще-то, если коллекция пуста, то непонятно, что возвращать.
Т.е.
TRet Invoke(PARAMS)
{
  if(!m_DelegateList.empty())
  {
      for(......) (*it)->Invoke(ARGS);
      return m_DelegateList.back()->Invoke(ARGS);
  }
  else
  {
    // на выбор
    assert(! "нечего вызывать, нечего возвращать, щас вылечу нафиг");
    throw SomeDelegateException();
    return TRet();
  }
}


А ещё остаётся за кадром такой момент, как изменение списка во время его обхода.
Тут нужна или двойная буферизация,
vector<IDelegate*> snapshot; // вектор дешевле списка, поэтому копировать удобнее в него
snapshot.reserve(m_DelegateList.size());
snapshot.insert(m_DelegateList.begin(), m_DelegateList.end());
// далее - как с гусём :)

... или внимательность к свежедобавленным и свежеудаляемым элементам.
Свежедобавленные в конец — будут учитываться, поскольку мы проверяем фактический конец на каждой итерации цикла. (А вот если бы использовали for_each, то там запомнили бы итератор на предпоследний элемент на момент начала работы).
Свежеудалённые — болезненнее, так как может быть удалён текущий элемент, а итератор на него станет невалидным.
Не реентерабельная версия Invoke — в паре с Remove и RemoveAll может выглядеть так
DelegateList::iterator m_next;
.....
void Remove(IComparableDelegate* pDelegate)
{
  .....
  if(it == m_next)
    ++m_next;
  m_DelegateList.erase(it);
  .....
}
void RemoveAll()
{
  .....
  m_next = m_DelegateList.end();
}
TRet Invoke(PARAMS)
{
  DelegateList::iterator it = m_DelegateList.begin();
  while(true)
  {
    if(it == m_DelegateList.end()) { assert(!"всё-таки вылетели!!!"); return TRet(); }
    m_next = it; ++m_next;
    if(m_next == m_DelegateList.end()) { return (*it)->Invoke(ARGS); }
    (*it)->Invoke(ARGS);
    it = m_next;
  }
}

Реентерабельная... у, это сложно.
Перекуём баги на фичи!
Re[3]: "в языке C++ операторы не наследуются (?)"
От: jazzer Россия Skype: enerjazzer
Дата: 27.11.08 00:28
Оценка: +1
Здравствуйте, johny5, Вы писали:

А>>PS

А>> По ходу чтения возникла мысль: не проще ли генерировать классы на каком-либо скрипте?

J>Кстати, не знает ли кто простой и проверенный способ в студии по описанию класса генерить операторы ==, !=, =; конструктор по умолчанию, копирования, макросы сериализации (тут ессно нуно ручками будет что то в чём то прописать), и прочий мегатонный мусор. Плюс стандартные #ifndef BLABLABLA_H_INCL__ мусор ___ #define BLABLABLA_H_INCL__ мусор ___ и #include в .cpp файле.


J>Чтоб вот нажал кнопку, бах и всё на месте..

J>Желательно было б конечно в идеале уметь обновлять все эти структуры при обновлении полей.

Кстати, даже если ты будешь пользоваться своим макросом, все равно операторы лучше добавлять через Boost.Operators — там тебе придется добавить всего по одной функции на оператор, остальные она сгенерит сама, пользуясь этой функцией.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Проблема с копированием делегатов?
От: Аноним  
Дата: 31.01.09 18:16
Оценка:
Здравствуйте, Александр Шаргин, Вы писали:

АШ>Статья :

АШ>Делегаты на C++
Автор(ы): Александр Шаргин
Дата: 19.03.2003
Делегаты в CLR удобны, типобезопасны и эффективны. Последнее время на форумах RSDN часто поднимается вопрос о том, можно ли реализовать делегаты с аналогичными свойствами, оставаясь в рамках "чистого" C++. Оказывается, это вполне возможно. В этой статье я покажу, как это сделать.


АШ>Авторы :

АШ>Александр Шаргин

АШ>Аннотация :

АШ>Делегаты в CLR удобны, типобезопасны и эффективны. Последнее время на форумах RSDN часто поднимается вопрос о том, можно ли реализовать делегаты с аналогичными свойствами, оставаясь в рамках "чистого" C++. Оказывается, это вполне возможно. В этой статье я покажу, как это сделать.

Возникла проблема с копированием делегатов от одного обьекта к другому:


    C_DELEGATE(const C_DELEGATE<TRet TEMPLATE_ARGS>& x_right)
    {
        this.RemoveAll();
        gslIDelegate* delegate_ptr=x_right.GetDelegates(true);
        while(delegate_ptr!=0)
        {
            this.operator+=(delegate_ptr); //Здесь копируются указатели
            delegate_ptr=x_right.GetDelegates();
        };
    };

    C_DELEGATE<TRet TEMPLATE_ARGS>& operator=(C_DELEGATE<TRet TEMPLATE_ARGS>& x_right)
    {
        RemoveAll();
        gslIDelegate* delegate_ptr=x_right.GetDelegates(true);
        while(delegate_ptr!=0)
        {
            operator+=(delegate_ptr); //Здесь копируются указатели
            delegate_ptr=x_right.GetDelegates();
        };

        return *this;
    };

        void RemoveAll()
        {
                DelegateList::iterator it;
                for(it = m_DelegateList.begin(); it != m_DelegateList.end(); ++it)
                   delete (*it); //Здесь указатели прибиваются

                m_DelegateList.clear();
        InitIteratorDelegates();
       }

       ~C_DELEGATE() { RemoveAll(); }


То есть такой псевдокод не работает:

   class Object
   {
      C_DELEGATE* object_delegate;

      Object()
      {
         object_delegate=new C_DELEGATE();
      };

      Object(const Object& x_right)
      {
         object_delegate=new C_DELEGATE();
         *object_delegate=*(x_right.object_delegate); //Здесь скопируются указатели
      };

      Object& operator=(const Object& x_right)
      {
          *object_delegate=*(x_right.object_delegate); //Здесь скопируются указатели
          return *this;
      };

      C_DELEGATE* get_delegate() const
      {
         return object_delegate;
      };

      ~Object()
      {
         delete object_delegate;
      };
   };

   class Events
   {
       void Test();
   };

   //Тогда код:

   Events events;

   void main()
   {
      Object object2;

      {
         Object object1;
         object1.get_delegate()->operator +=(NewDelegate(events, &Events::Test));

         Object object2=object1; //Хочу скопировать объект вместе с его делегатами;
      }; //Здесь object1 рушится вместе с указателями в ~C_DELEGATE, а указатели делегатов в object2 становятся не валидными 
      
      object2.get_delegate()->operator ()(); //CRASH! потому как object1 забрал в небытие указатели на делегаты с собой.
   };


Понятно что в C_DELEGATE(const C_DELEGATE<TRet TEMPLATE_ARGS>& x_right) и operator== нужно копировать не указатели а делать их реальные копии, но что то не могу понять как это сделать?

Спасибо!
Re[2]: Проблема с копированием делегатов?
От: Аноним  
Дата: 31.01.09 18:23
Оценка:
Поправка в коде:

  //Тогда код:

   Events events;

   void main()
   {
      Object object2;

      {
         Object object1;
         object1.get_delegate()->operator +=(NewDelegate(events, &Events::Test));

         object2=object1; //Хочу скопировать объект вместе с его делегатами;
      }; //Здесь object1 рушится вместе с указателями в ~C_DELEGATE, а указатели делегатов в object2 становятся не валидными 
      
      object2.get_delegate()->operator ()(); //CRASH! потому как object1 забрал в небытие указатели на делегаты с собой.
   };
Re[3]: Up...
От: Аноним  
Дата: 01.02.09 22:34
Оценка:
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.