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

 

хороший пример от @fxsaber , но одна проблема - а как удалить указатель на обьект автоматически? 

 
Igor Makanu:

хороший пример от @fxsaber , но одна проблема - а как удалить указатель на обьект автоматически? 

Удаление из массива указателей в деструкторе же. при вызове delete для указателя любого потомка. Или не про то?

 
Igor Makanu:

хороший пример от @fxsaber , но одна проблема - а как удалить указатель на обьект автоматически? 

Удалив объект. 

 
Aleksey Mavrin:

Удаление из массива указателей в деструкторе же. при вызове delete для указателя любого потомка. Или не про то?

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

void OnStart()
{
   A *a = new A;;
}

хочу чтобы этот код работал без вызова delete a

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

пробовал создавать объект BASE b и при окончании программы вместе с b - удалить все оьекты BASE в цикле...что то пошло не так - переполнение стека получаю


ЗЫ: хотел покрутить модель акторов, код от @fxsaber удобный, можно создать актор путем обьявления указателя из актора, а вот корректно завершить всю программу не получается 

 
Igor Makanu:

корректно завершить всю программу не получается 

Посмотрите VIRTUAL_DELETE-класс в Virtual-библиотеке. Подчищать можно таким же способом.

 
fxsaber:

Посмотрите VIRTUAL_DELETE-класс в Virtual-библиотеке. Подчищать можно таким же способом.

ОК, посмотрю, но не уверен в успехе этого мероприятия (((

 
Igor Makanu:

хочу чтобы этот код работал без вызова delete a

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

пробовал создавать объект BASE b и при окончании программы вместе с b - удалить все оьекты BASE в цикле...что то пошло не так - переполнение стека получаю


ЗЫ: хотел покрутить модель акторов, код от @fxsaber удобный, можно создать актор путем обьявления указателя из актора, а вот корректно завершить всю программу не получается 

аа, понял проблему. Вот поэтому в т.ч. мне удобнее использовать коллекции (в т.ч. одиночки), которые очищаются при удалении.

А вызвать для общей коллекции один раз delete как-то не лень :), ну  или держать её статической, чтобы деструктор вызывался автоматически.

з.ы. еще простое решение до кучи, вместо массива использовать CArrayObj из СБ, или подобный динамический контейнер.
 
Aleksey Mavrin:

з.ы. еще простое решение до кучи, вместо массива использовать CArrayObj из СБ, или подобный динамический контейнер.

эта задача решена, вот универсальное решение https://www.mql5.com/ru/forum/85652/page16#comment_12346740

наследуйтесь от CObject и можете работать со списками без проблем

Aleksey Mavrin:

которые очищаются при удалении.

задача как раз обратная - не очищать при выходе из локальной области видимости указатели на обьект, НО очищать массивы указателей при окончании программы


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


что Вы посчитаете за актор - минимальный функционал из ЕА, или же полностью ЕА - не важно, важно, что это некая группа конечных автоматов, которые работают асинхронно

да... сама суть этой концепции - актор может создавать актор, применительно к возможностям MQL - это и есть указатель на обьект

 
Igor Makanu:

ОК, посмотрю, но не уверен в успехе этого мероприятия (((

class DELETE_BASE
{
   public:
   ~DELETE_BASE(){ BASE::DeleteAll(); }
};


class BASE {
private:
   static BASE* Objects[];
   static int arraysize;
   const static DELETE_BASE DeleteBase;
   
public:
    static void DeleteAll( void )
   {
      int Size = ::ArraySize(BASE::Objects);
      for (int i = Size - 1; i >= 0; i--)
         delete BASE::Objects[i];
      return;
   }
   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 0;
   virtual void 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[];
const static DELETE_BASE DeleteBase;
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+


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 = new A;
B b[2];

//+------------------------------------------------------------------+
void OnInit()
{
   BASE::AllInit();
}
//+------------------------------------------------------------------+
void OnDeinit( const int Reason )
{
   BASE::AllDeinit(Reason);
}
//+------------------------------------------------------------------+
void OnTick()
{
   BASE::AllTick();
}
//+------------------------------------------------------------------+


кажется работает, потестировать еще нужно

@fxsaber , огромное спасибо! .... есть конечно вопрос, зачем так писать:

const static DELETE_BASE DeleteBase;

вообще не понимаю эту строку, пока так не написал, всегда в своих вариантах кода получал переполнение стека

 
Igor Makanu:


кажется работает, потестировать еще нужно

@fxsaber , огромное спасибо! .... есть конечно вопрос, зачем так писать:

вообще не понимаю эту строку, пока так не написал, всегда в своих вариантах кода получал переполнение стека

Чтобы не перекрывать область видимости. 

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