OnTick() не работает в экземпляре класса? - страница 3

 
fxsaber:

Не понял. Можете написать только нужные события

У Вас в первом примере абстрактный метод, а во втором просто пустые виртуальные. И да, про костыли я тоже соглашусь. При абстрактных методах, необходима реализация, хотя бы в виде заглушек и опять надежда на "умный" компилятор, а во втором случае, та же тема с компилятором плюс потенциальный баг из-за опечаток.
 
Vladimir Simakov:
а во втором случае, та же тема с компилятором плюс потенциальный баг из-за опечаток.

опечатки проверил, если реализацию не напишешь, то получим function 'B::OnDeinit' must have a body

в общем меня устраивает как и по скорости так и по краткости такой код

class BASE {
private:
   static BASE* Objects[];
   static int arraysize;

public:
   BASE()
   {
      BASE::arraysize = ::ArrayResize(BASE::Objects, ::ArraySize(BASE::Objects) + 1);
      BASE::Objects[arraysize - 1] = &this;
   }

   ~BASE()
   {
      const int Size = ::ArraySize(BASE::Objects);

      for (int i = Size - 1; i >= 0; i--)
         if (BASE::Objects[i] == &this) {
            for (int j = i; j < Size - 1; j++)
               BASE::Objects[j] = BASE::Objects[j + 1];

            ::ArrayResize(BASE::Objects, Size - 1);

            break;
         }
      BASE::arraysize = ::ArraySize(BASE::Objects);
   }

   virtual void OnInit() =0;
   virtual void OnTick() =0;
   virtual void OnDeinit( const int )=0;

   static void AllInit()
   {
      for (int i = 0; i < BASE::arraysize; i++)
         BASE::Objects[i].OnInit();
   }

   static void AllTick()
   {
      for (int i = 0; i < BASE::arraysize; i++)
         BASE::Objects[i].OnTick();
   }

   static void AllDeinit( const int Reason )
   {
      for (int i = 0; i < BASE::arraysize; i++)
         BASE::Objects[i].OnDeinit(Reason);
   }
};

static int BASE::arraysize = 0;

static BASE* BASE::Objects[];

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnInit()
{
   BASE::AllInit();
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
{
   BASE::AllTick();
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit( const int Reason )
{
   BASE::AllDeinit(Reason);
}


class A : BASE {
   virtual void OnInit() override               { Print(__FUNCSIG__); } 
   virtual void OnTick() override               { Print(__FUNCSIG__); }
   virtual void OnDeinit( const int ) override  { Print(__FUNCSIG__); }
};

class B : BASE {
   virtual void OnInit() override               { Print(__FUNCSIG__); }
   virtual void OnTick() override               { Print(__FUNCSIG__); }
   virtual void OnDeinit( const int ) override; // { Print(__FUNCSIG__); }
};

A a;
B b[2];
//+------------------------------------------------------------------+


пару раз запустил в терминале, все работает:

2019.11.01 15:10:05.387 tst (EURUSD,H1) void A::OnInit()

2019.11.01 15:10:05.388 tst (EURUSD,H1) void B::OnInit()

2019.11.01 15:10:05.388 tst (EURUSD,H1) void B::OnInit()

2019.11.01 15:10:07.062 tst (EURUSD,H1) void A::OnTick()

2019.11.01 15:10:07.062 tst (EURUSD,H1) void B::OnTick()

2019.11.01 15:10:07.062 tst (EURUSD,H1) void B::OnTick()

2019.11.01 15:10:33.639 tst (EURUSD,H1) void A::OnDeinit(const int)

2019.11.01 15:10:33.639 tst (EURUSD,H1) void B::OnDeinit(const int)
2019.11.01 15:10:33.639 tst (EURUSD,H1) void B::OnDeinit(const int)


 

Ого, как тема развилась!

Не могли бы вы на пальцах объяснить суть этой конструкции? Я не программист и оказалось тяжело понять что к чему.

Objects[] - это массив объектов унаследованных классов, и функция AllTick() вызывает событие в них?

Для чего используется ArrayResize в конструкторе?

Третий параметр ArrayResize опускается?

int    reserve_size=0        // резервное значение размера (избыточное)

Что означает следующая запись?

OnTick() =0;


Мне тоже показалось, что не очень здорово 

писать один суперкласс, который будет управлять "стадом неразумных мелких классов

 
Sunriser:

Ого, как тема развилась!

Не могли бы вы на пальцах объяснить суть этой конструкции? Я не программист и оказалось тяжело понять что к чему.

Objects[] - это массив объектов унаследованных классов, и функция AllTick() вызывает событие в них?

да, но нужно прописать для каждого класса этот метод или сделать пустой метод {  }

Sunriser:

Для чего используется ArrayResize в конструкторе?

Третий параметр ArrayResize опускается?

да опускается, вернее по умолчанию, справка или распринтуйте увидите, размер массива указателей нужно же изменять если новые наследники будут?

Sunriser:

Что означает следующая запись?

OnTick() =0;

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

 
Sunriser:

Мне тоже показалось, что не очень здорово ...

Так ведь этот суперкласс предназначен специально для классов, у которых один метод должен вызываться на каждом тике.

 
Sunriser:


Что означает следующая запись?

OnTick() =0;

Абстрактный метод - обязателен к реализации в наследниках
 
Dmitry Fedoseev:

Так ведь этот суперкласс предназначен специально для классов, у которых один метод должен вызываться на каждом тике.

А я чтобы к такому супер-классу не привязываться ввёл систему коллекций, для каждой ветки иерархии своя коллекция со своими специфическим наборов событий  и т.о. нужно вызывать методы нескольких коллекций, а не одного для всех супер-класса. Плюсы и минусы есть у обоих подходов, мой мне как-то ближе), и кажется гибче, хотя всё зависит от общей структуры проекта, если количество объектов невысоко и постоянно, то не влом и скопипастить для каждого)

 
Aleksey Mavrin:

А я чтобы к такому супер-классу не привязываться ввёл систему коллекций, для каждой ветки иерархии своя коллекция со своими специфическим наборов событий  и т.о. нужно вызывать методы нескольких коллекций, а не одного для всех супер-класса. Плюсы и минусы есть у обоих подходов, мой мне как-то ближе), и кажется гибче, хотя всё зависит от общей структуры проекта, если количество объектов невысоко и постоянно, то не влом и скопипастить для каждого)

Мне тоже больше нравится, когда все делается явно.

 
Если по изучаете архитектуру стандартных классов, то найдете много полезных рецептов.
 
Alexandr Gavrilin:
Если по изучаете архитектуру стандартных классов, то найдете много полезных рецептов.

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

Причина обращения: