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

 
Alexey Viktorov #:
В Array.mqh есть виртуальная функция QuickSort() и в ArrayObj.mqh тоже, но не виртуальная.

Не знаю, почему она не вритуальная в CArrayObj.

Интересно, что в CArrayDouble функция QuickSort() объявлена как виртуальная, а в CArrayObj функция QuickSort() объявлена без virtual. Хоть и там и там она в protected секции, то есть, допускается дальнейшее наследование.

Также не понимаю, почему стандартная библиотека не использует override совсем. С этим ключевым словом сильно прозрачнее было бы. А так я без тестов затрудняюсь понять, перегрузка это или переопределение (смущает параметр со значением по умолчанию):


Руками добавил override для QuickSort() в CArrayObj и скомпилировалось без ошибок. Наверное все-таки переопределение. Но что бы наверняка убедиться, нужно тестировать.

Также не понимаю, что здесь вызывается (это рекурсия или вызов метода базового класса; можно же было явно указать с помощью :: 😄):

void CArrayObj::QuickSort(int beg,int end,const int mode)
  {
   int      i,j;
   CObject *p_node;
   CObject *t_node;
//--- sort
   i=beg;
   j=end;
   while(i<end)
     {
      //--- ">>1" is quick division by 2
      p_node=m_data[(beg+end)>>1];
      while(i<j)
        {
         while(m_data[i].Compare(p_node,mode)<0)
           {
            //--- control the output of the array bounds
            if(i==m_data_total-1)
               break;
            i++;
           }
         while(m_data[j].Compare(p_node,mode)>0)
           {
            //--- control the output of the array bounds
            if(j==0)
               break;
            j--;
           }
         if(i<=j)
           {
            t_node=m_data[i];
            m_data[i++]=m_data[j];
            m_data[j]=t_node;
            //--- control the output of the array bounds
            if(j==0)
               break;
            j--;
           }
        }
      if(beg<j)
         QuickSort(beg,j,mode);
      beg=i;
      j=end;
     }
  }
 
Vladislav Boyko #:

...Также не понимаю, что здесь вызывается (это рекурсия или вызов метода базового класса; можно же было явно указать с помощью :: 😄):

Там рекурсия. В базовом классе QuickSort() - пустышка.

 
Vladislav Boyko #:
Интересно, что в CArrayDouble функция QuickSort() объявлена как виртуальная, а в CArrayObj функция QuickSort() объявлена без virtual. Хоть и там и там она в protected секции, то есть, допускается дальнейшее наследование.

Вроде, достаточно один раз в родительском классе объявить ф-цию виртуальной. Или зря мне так кажется?

 
Vladislav Boyko #:


Также не понимаю, что здесь вызывается (это рекурсия или вызов метода базового класса; можно же было явно указать с помощью :: 😄):


Рекурсия.
 
JRandomTrader #:
Или зря мне так кажется?

Вам не кажется

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

Ilyas, 2023.03.27 23:16

Что будете делать, если ваш класс был порождён от класса, в котором функция, которую больше не должны переопределять, была объявлена виртуальной

Тем не менее, в одном наследнике (CArrayDouble) уже виртуальная функция с virtual, в другом (CArrayObj) - без.

 
Denis Kirichenko #:

Там рекурсия. В базовом классе QuickSort() - пустышка.

Sergey Gridnev #:

Рекурсия.

Понял, спасибо.

По поводу перегружен/переопределен, наверное тот код довольно очевидный для человека, который наизусть помнит Алгоритм выбора перегруженной функции и перегрузку методов. Но лично я хотел бы видеть модификатор override, хуже он не сделал бы.

 
Vladislav Boyko #:

Не знаю, почему она не вритуальная в CArrayObj.

Интересно, что в CArrayDouble функция QuickSort() объявлена как виртуальная, а в CArrayObj функция QuickSort() объявлена без virtual. Хоть и там и там она в protected секции, то есть, допускается дальнейшее наследование.

Также не понимаю, почему стандартная библиотека не использует override совсем. С этим ключевым словом сильно прозрачнее было бы. А так я без тестов затрудняюсь понять, перегрузка это или переопределение (смущает параметр со значением по умолчанию):


Руками добавил override для QuickSort() в CArrayObj и скомпилировалось без ошибок. Наверное все-таки переопределение. Но что бы наверняка убедиться, нужно тестировать.

Также не понимаю, что здесь вызывается (это рекурсия или вызов метода базового класса; можно же было явно указать с помощью :: 😄):

Наверное override просто погремушка для понимания при чтении кода.


В общем я понял так:

В классе CArray() функция объявлена виртуальной. В наследнике CArrayObj() уже не виртуальная. Следовательно если писать что-то потомком от CArrayObj() то функция не будет перегружена, или переопределена, я не знаю как правильно выразиться.

НО!!! Если в CArrayObj() её изменить и дописать ей virtual то в наследнике от CArrayObj() можно будет ещё раз написать свою реализацию QuickSort()

Хотя, это может быть совсем неправильно. Запутает так, что никогда не распутаешь…

 
Alexey Viktorov #:

Наверное override просто погремушка для понимания при чтении кода.

Нет.
Компилятор при наличии этого ключевого слова проверяет наличие переопределяемого метода в родительском классе и при отсутствии сообщает об ошибке. Без override стоит ошибиться в параметрах и - привет, новый метод.
 
Alexey Viktorov #:

В общем я понял так:

В классе CArray() функция объявлена виртуальной. В наследнике CArrayObj() уже не виртуальная. Следовательно если писать что-то потомком от CArrayObj() то функция не будет перегружена, или переопределена, я не знаю как правильно выразиться.

НО!!! Если в CArrayObj() её изменить и дописать ей virtual то в наследнике от CArrayObj() можно будет ещё раз написать свою реализацию QuickSort()

Хотя, это может быть совсем неправильно. Запутает так, что никогда не распутаешь…

Смотрите этот пост и следующие два.

Вот код, который отвечает на ваш вопрос.

 
Sergey Gridnev #:
Нет.
Компилятор при наличии этого ключевого слова проверяет наличие переопределяемого метода в родительском классе и при отсутствии сообщает об ошибке. Без override стоит ошибиться в параметрах и - привет, новый метод.

То-есть в СБ отсутствие override к методу QuickSort() из CArrayObj() можно считать ошибкой?