Учёба. Классы. Нужна помощь. - страница 22

 
Vladislav Boyko #:

Наверное потому, что с dynamic_cast не упадет, а без него упадет (опять-же, не точно, я не проверял)

Так если упадёт, то, может, оно и хорошо? Так хоть увидим, насколько злобными Буратинами мы себе стали в процессе стреляния себе в ногу )

Пример из справки описывает общую гипотетическую ситуацию. Там, где будет использоваться метод Compare, не должно возникать даже возможности сравнения объектов разного типа. Если каким-то чудом такое случилось, то надо переписывать код, а не позволять продолжать ему работать.

Но тут каждый волен сам решать, что ему больше по душе.

 
Georgiy Merts #:

Я выше прилагал свою реализацию метода Compare:

То есть, внутри функции Compare - мы преобразуем указатель на CObject к указателю на реальный объект (наследник CObject), и проводим функции сравнения уже между этими указателями на реальные объекты. 

Вот, как раз для этого и удобны виртуальные функции сравнения. 

Сравните экземпляр CFrameData с экземпляром InvalidClass:

class InvalidClass : public CObject {};

Что произойдет? Логи будут? Или упадет раньше, чем должно выполниться логирование?

Я не знаю ответ на свои вопросы, мне просто интересно.

Yuriy Bykov #:
Там, где будет использоваться метод Compare, не должно возникать даже возможности сравнения объектов разного типа.

Если вы уверены, что не произойдет сравнения разных производных классов, то да, в таком случае пофигу. Можно просто кастовать указатель без проверки и спокойно сравнивать.

Зависит от проекта и от разработчика/разработчиков.

 
Denis Kirichenko #:

Ну почему же сразу экзамен. Насколько понимаю, тут всё на добровольных началах: Вы копаете - мы закапываем, или мы копаем - Вы закапываете ))

Да, метод сравнения вызывается как правило из других. Но в целях упрощения примера я вызвал его напрямую. Чаще всего метод используется в сортировках. Свои сортировки тоже можно писать...

Ну я не имею права спорить, а вот переспросить хочу…

Где в сортировке Compare()

//+------------------------------------------------------------------+
//| Sorting an array in ascending order                              |
//+------------------------------------------------------------------+
void CArray::Sort(const int mode)
  {
//--- check
   if(IsSorted(mode))
      return;
   m_sort_mode=mode;
   if(m_data_total<=1)
      return;
//--- sort
   QuickSort(0,m_data_total-1,mode);
  }

Тут другая виртуальная функция QuickSort(), и как я понял можно сортировать не весь массив, а только его часть. И для этого надо писать свою функцию QuickSort()

А что вы имеете ввиду «Свои сортировки тоже можно писать»? Не ужели есть другие направления сортировки, отличные от «по возрастанию» или «по убыванию». В MQL4 была возможность указать направление сортировки, а в MQL5 от этого отказались. Достаточно изменить направление индексации и вот вам «обратная» сортировка.

 
Alexey Viktorov #:
Не ужели есть другие направления сортировки, отличные от «по возрастанию» или «по убыванию».
Допустим, ваш объект содержит цену, время, объём и имя инструмента. Как коллекцию этих объектов отсортировать по возрастанию?
 
Sergey Gridnev #:
Допустим, ваш объект содержит цену, время, объём и имя инструмента. Как коллекцию этих объектов отсортировать по возрастанию?

По возрастанию чего? Времени, цены или по имени инструмента?

 
Alexey Viktorov #:

По возрастанию чего? Времени, цены или по имени инструмента?

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

 
Yuriy Bykov #:

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

Изначально я не об этом говорил. Ну да ладно, проехали.

Вот не могу понять как из сортировки вызывается Compare() где это обращение к этому методу? Я уже показал, из метода поиска чётко видно… А из метода сортировки, ну никак не вижу.

На всякий случай, чтобы вы не перелистывали страницы вот сортировка

   virtual void      QuickSort(int beg,int end,const int mode=0) { m_sort_mode=-1; }
//+------------------------------------------------------------------+
//| Sorting an array in ascending order                              |
//+------------------------------------------------------------------+
void CArray::Sort(const int mode)
  {
//--- check
   if(IsSorted(mode))
      return;
   m_sort_mode=mode;
   if(m_data_total<=1)
      return;
//--- sort
   QuickSort(0,m_data_total-1,mode);
  }

и вот поиск

//+------------------------------------------------------------------+
//| Search of position of element in a sorted array                  |
//+------------------------------------------------------------------+
int CArrayObj::Search(const CObject *element) const
  {
   int pos;
//--- check
   if(m_data_total==0 || !CheckPointer(element) || m_sort_mode==-1)
      return(-1);
//--- search
   pos=QuickSearch(element);
   if(m_data[pos].Compare(element,m_sort_mode)==0)
      return(pos);
//--- not found
   return(-1);
  }
 
Vladislav Boyko #:

dynamic_cast, наверное. Но это сильно сомнительное удовольствие, ка по мне. Я бы не наследовался от CObject, а написал бы свои велосипедные сравнения и сортировки.

И то, хз, какие там подводные камни. Ни разу так не делал.

Хм, интересно. Я, вероятно, сменил свое мнение в результате этого обсуждения. Нужно присмотреться к стандартной библиотеке; думаю, когда начну лучше ориентироваться в стандартной библиотеке, у меня поубавится желания писать велосипеды.

 
Vladislav Boyko #:

Я бы не наследовался от CObject

Заметил, что популярно наследоваться от этой СБ. У самого не возникала такая необходимость.
 
Alexey Viktorov #:
Вот не могу понять как из сортировки вызывается Compare() где это обращение к этому методу?

Смотрите производные от CArray. ArrayObj.mqh, например - там в QuickSort() используется Compare()