Обсуждение статьи "Основы программирования на MQL5 - Списки" - страница 6

 
papaklass:

Господа, может попробуем дискутировать предметно? :)

Правильный лист не должен для использования его для произвольного класса требовать явной имплементации нового класса.

Поэтому правильная имплементация должна опираться на шаблоны.

Справедливости ради, я не уверен, что это реализуемо на представленном уровне шаблонов.

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

 
TheXpert:


Правильный лист не должен для использования его для произвольного класса требовать явной имплементации нового класса...

Правильно понимаю, что даже если узлы (элементы списка) имеют разный тип и способ связи между собой, то всё равно список должен иметь одну и ту же реализацию, т.е. относится к одному и тому же типу данных? Условно CList  должен включать в себя разные типы узлов (CSingleNode, CDoubleNode и т.д.)...
 
denkir:
Условно CList  должен включать в себя разные типы узлов...

Зачем? ) Контейнер -- это совокупность однородных объектов.

Разница самих объектов может быть реализована полиморфизмом в рамках уже объектов и к списку никакого отношения не имеет.

Когда нужно использовать указатели в MQL5
Когда нужно использовать указатели в MQL5
  • 2010.03.25
  • MetaQuotes Software Corp.
  • www.mql5.com
Все объекты в MQL5 по умолчанию передаются по ссылке, но есть возможность использовать и указатели объектов. При этом есть опасность получить в качестве параметра функции указатель неинициализированного объекта. В этом случае работа программы будет завершена критически с последующей выгрузкой. Автоматически создаваемые объекты как правило такой ошибки не вызывают, и в этом отношении они достаточно безопасны. В этой статье мы попробуем разобраться в чем разница между ссылкой и указателей, когда оправдано использование указателей и как написать безопасный код с использованием указателей.
 
TheXpert:

Зачем? ) Контейнер -- это совокупность однородных объектов.

Разница самих объектов может быть реализована полиморфизмом в рамках уже объектов и к списку никакого отношения не имеет.

Это понятно, что конкретный список включает в свой состав однородные узлы. Я имел в виду, что связи между узлами в этом списке могут быть разными, что и требует разного типа списка для каждого типа узлов. Если создать один и тот же класс списка для узлов разного типа, то это было бы здорово... лично я сам пока не пробовал... надо подумать над высшим уровнем абстракции...
 
TheXpert:

Правильный лист не должен для использования его для произвольного класса требовать явной имплементации нового класса.

Поэтому правильная имплементация должна опираться на шаблоны.

Справедливости ради, я не уверен, что это реализуемо на представленном уровне шаблонов.

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

Как мне и не приятно признавать, здесь эксперт прав. В идеале, класс листа должен быть реализован на шаблонах. Хотя стандартный CList и реализован на CObject
 

То, что предлагает TheXpert, кажется понятно.

Если я правильно уловил его идею, то все методы некоего абстрактного списка должны автоматом узнавать "свой" узел (это и есть полиморфизм).

В статье например есть пользовательские классы CiSingleList (Рис.9), CDoubleList (Рис.11), CiUnrollDoubleList (Рис.12), CiCircleDoubleList (Рис.13).

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

Когда нужно использовать указатели в MQL5
Когда нужно использовать указатели в MQL5
  • 2010.03.25
  • MetaQuotes Software Corp.
  • www.mql5.com
Все объекты в MQL5 по умолчанию передаются по ссылке, но есть возможность использовать и указатели объектов. При этом есть опасность получить в качестве параметра функции указатель неинициализированного объекта. В этом случае работа программы будет завершена критически с последующей выгрузкой. Автоматически создаваемые объекты как правило такой ошибки не вызывают, и в этом отношении они достаточно безопасны. В этой статье мы попробуем разобраться в чем разница между ссылкой и указателей, когда оправдано использование указателей и как написать безопасный код с использованием указателей.
 
Хорошо, что справедливость хоть иногда торжествует. ))
 
denkir:
Это понятно, что конкретный список включает в свой состав однородные узлы. Я имел в виду, что связи между узлами в этом списке могут быть разными, что и требует разного типа списка для каждого типа узлов. Если создать один и тот же класс списка для узлов разного типа, то это было бы здорово... лично я сам пока не пробовал... надо подумать над высшим уровнем абстракции...
Тип узла нужен только один. Смотрите реализацию стандартного CObject и реализацию коллекций CArray, CList, CTree: Справочник MQL5 --> Стандартная библиотека --> Классы для организации данных.
Документация по MQL5: Стандартная библиотека
Документация по MQL5: Стандартная библиотека
  • www.mql5.com
Стандартная библиотека - Документация по MQL5
 
...не мешки ворочать. Практически кто покажет?
 
denkir:

То, что предлагает TheXpert, кажется понятно.

Если я правильно уловил его идею, то все методы некоего абстрактного списка должны автоматом узнавать "свой" узел (это и есть полиморфизм).

В статье например есть пользовательские классы CiSingleList (Рис.9), CDoubleList (Рис.11), CiUnrollDoubleList (Рис.12), CiCircleDoubleList (Рис.13).

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

Что тут кодировать-то?

#include <Object.mqh>
#include <Arrays\ArrayObj.mqh>

enum ENUM_CLASS_TYPE
{
   HUMAN,
   ANIMAL,
   CAR
};

class Community : public CObject
{
   public:
      ENUM_CLASS_TYPE TypeCommunity(){return type;}
   protected:
      Community(ENUM_CLASS_TYPE cType)
      {
          type = cType;
      }
      
   private:
      ENUM_CLASS_TYPE type;
};

class Human : public Community
{
   public:
      Human() : Community(HUMAN){;}
      int IQ(){return 90;}
};

class Animal : public Community
{
   public:
      Animal() : Community(ANIMAL){;}
      int CountLegs(){return 4;}
};

class Car : public Community
{
   public:
      Car() : Community(CAR){;}
      int Speed(){return 20;}
};

void OnStart()
{
   CArrayObj elements;
   CObject* object = NULL;
   while(elements.Total() < 100)
   {
      switch(rand()%3)
      {
         
         case HUMAN:
            object = new Human();
            break;
         case ANIMAL:
            object = new Animal();
            break;
         case CAR:
            object = new Car();
            break;
      }
      elements.Add(object);
   }
   while(elements.Total() > 0)
   {
      Community* AnyObject = elements.At(0); 
      switch(AnyObject.TypeCommunity())
      {
         case HUMAN:
         {
            Human* human = AnyObject;
            printf("Element is Human, it's IQ is: " + (string)human.IQ());
            break;
         }
         case ANIMAL:
         {
            Animal* animal = AnyObject;
            printf("Element is anima, it has " + (string)animal.CountLegs() + " legs.");
            break;
         }
         case CAR:
         {
            Car* car = AnyObject;
            printf("Element is car. It has speed " + (string)car.Speed() + " km/h");
            break;
         }
      }
      elements.Delete(0);
   }
}
Первый класс, вторая четверть. К сожалению без посредника Community не обойтись, потому что MQL5 обладает крайне слабым контролем типов. Но имейся в распоряжении функция ClassToString, наподобии EnumToString() все можно было бы оргназиовать гораздо изящней и легче. 
Причина обращения: