Как избежать дублирования кода?

 
Подскажите пути решения следующей задачи:

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

Как можно собрать весь код так, чтобы внутри каждой такой функции не пришлось бы снова и снова прописывать вручную один и тот же цикл с общими условиями, а добавлять только необходимое?
 
leon_17:
Подскажите пути решения следующей задачи:

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

Как можно собрать весь код так, чтобы внутри каждой такой функции не пришлось бы снова и снова прописывать вручную один и тот же цикл с общими условиями, а добавлять только необходимое?

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

 
Vasiliy Sokolov #:

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

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

 
leon_17 #:

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

При вызове цикла, передавайте параметры-флаги и в зависимости от параметра(ов), "дергаете" нужные блоки в Вашем цикле

void MyCycle(const int param_1, const int param_2)
{
  for(int i = 0; i< param_2;i++)
  {
    switch(param_1)
    {
      case 0:
        continue;
      break;
      case 1:
        //......
      break;
    }
  } 
}
 
Высшее образование могло бы помочь. 
 
prostotrader #:

При вызове цикла, передавайте параметры-флаги и в зависимости от параметра(ов), "дергаете" нужные блоки в Вашем цикле

Ну, да... спасибо! А если без постоянного перебора вариантов на каждой итерации?

 
leon_17 #:

Ну, да... спасибо! А если без постоянного перебора вариантов на каждой итерации?

Разбейте Ваш цикл на несколько (в одной функции), и между маленькими циклами делайте (не делайте) логические операции.

 
leon_17:
Подскажите пути решения следующей задачи:

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

Как можно собрать весь код так, чтобы внутри каждой такой функции не пришлось бы снова и снова прописывать вручную один и тот же цикл с общими условиями, а добавлять только необходимое?

Виртуальный метод использовать. Цикл в базовом классе, а дополнительные действия в виртуальном методе производного класса:

class C{
   public:
      double main(int a1,double a2){
         double r1,r2=0;
         for(int i=a1;i<a2;i++){
            fun(i,r1);
            r2+=r1;
         }   
         return r2;
      }
      virtual void fun(int & a1,double & a2){
      }
};

class C1:public C{
   public:
      virtual void fun(int & a1,double & a2){
         a2=(double)a1/100;
      }      
};


class C2:public C{
   public:
      virtual void fun(int & a1,double & a2){
         a2=(double)a1/1000;
      }      
};


void OnStart(){

   C1 c1;
   C2 c2;
      
   double r1=c1.main(0,10);
   double r2=c2.main(0,10);   
   
   Alert(r1," ",r2);

}

...

Еще можно указатель на функцию использовать. В основном цикле вызывать функцию по указателю. См. typedef

А указатель передавать как параметр основной функции.

 
Dmitry Fedoseev #:

Виртуальный метод использовать. Цикл в базовом классе, а дополнительные действия в виртуальном методе производного класса:

...

Еще можно указатель на функцию использовать. В основном цикле вызывать функцию по указателю. См. typedef

А указатель передавать как параметр основной функции.

Так все-таки вот оно чудо ООП. Я вот тоже смотрел в сторону виртуальной функции, но в ООП я пока новичок и не рискнул сам спрашивать о таком решении, потому что запутался бы в трех соснах.

Большое спасибо за пример Дмитрий! Буду изучать!

p.s. Также огромное спасибо за книгу по MQL5! Случайно попалась где-то в сети и оказалась очень серьезным подспорьем для перехода с MQL4. И больше всего заинтересовал как раз раздел ООП. Даже не представляю какого труда стоило выделить только самое ходовое, систематизировать эту информацию и дополнить ее примерами, но лично для меня эта книга стала как минимум дорожной картой в пространстве MQL5. Про ООП хотелось бы конечно побольше информации и примеров, но кто ищет, тот найдет! ) 

 
Dmitry Fedoseev #:

Виртуальный метод использовать. Цикл в базовом классе, а дополнительные действия в виртуальном методе производного класса:

...

Еще можно указатель на функцию использовать. В основном цикле вызывать функцию по указателю. См. typedef

А указатель передавать как параметр основной функции.

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

 
leon_17 #:

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

С указателями на функции кода будет меньше.

А вот что будет быстрее и будет ли разница по скорости, не знаю, надо пробовать.