Используете ли вы ООП в программировании на MQL4 и MQL5? - страница 10

 
Andrei:
Как класс может видеть внешние перменные? И как внешние переменные попадут динамически во внутрь класса через функции?
int num = 5;

class A
{
private:
     int i;
public:
     A(void)        { i=num; };
     A(const int y) { i=y; };
     
     void fun(void);
     void fun(const int j);
};

void A::fun(void)
{
     i=num;
}
void A::fun(const int j)
{
     i=j;
}

A a;
A *b = new A(num);
a.fun();
a.fun(num);
 
Более того, сам класс A - может иметь полностью виртуального предка:
int num = 5;

class AI
{
public:
     virtual void fun(void) = 0;
     virtual void fun(const int j) = 0;

}


class A: public AI
{
private:
     int i;
public:
     A(void)        { i=num; };
     A(const int y) { i=y; };
     
     virtual void fun(void);
     virtual void fun(const int j);
};

void A::fun(void)
{
     i=num;
}
void A::fun(const int j)
{
     i=j;
}

A a;
AI* b = new A(num);

// Много строк пропущено, пользователь получает указатель b

b.fun();
b.fun(num);

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

 

Пока логика класса не просматривается без поллитра)

Одна и та же функция вызывается в двух вариантах и еще и класс сам себя определяет дважды.

В общем баг в таком коде можно отлавливать годами))

 
Andrei:

Пока логика класса не просматривается без поллитра)

Одна и та же функция вызывается в двух вариантах и еще и класс сам себя определяет дважды.

В общем баг в таком коде можно отлавливать годами))

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

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

 

Вот еще пример, из моей Лиги ТС:

CEALeagueTradeSysemI* ltsTradeSystem = NULL;


int OnInit()
{
 
   // Получаем интерфейс ТС
   ltsTradeSystem = GetTradeSystem(Magic,RiskPercent,NULL);
   
   // Если интерфейс получить не удалось - возвращаем признак неудачи.
   if(ltsTradeSystem == NULL)
      return(INIT_FAILED);

   // Если интерфейс получен успешно - вызываем обработчик события OnInit() у этого интерфейса
   int iRes = ltsTradeSystem.TradeSystemOnInit();
   
   return(iRes);
};

void OnDeinit(const int iReason)
{
   // Если интерфейс торговой системы был успешно получен, 
   // Вызовем обработчик события OnDeinit() этого интерфейса,
   // удалим его и приравняем нулю.
   if(ltsTradeSystem != NULL)
      {
      ltsTradeSystem.TradeSystemOnDeinit(iReason);
      delete(ltsTradeSystem);
      ltsTradeSystem = NULL;
      };
};

void OnTick()
{
   // В функции OnTick() вызовем обработчик этого события у интерфейса
   ltsTradeSystem.TradeSystemOnTick();
};


Вот и весь эксперт, инкапсулирующий все 672 ТС.

В библиотеке есть только одна функция, экспортирующая интерфейс:

CEALeagueTradeSysemI* GetTradeSystem(ulong ulMagic,double dRiskPercent,ulong ulTSCode = NULL);

Указываете желаемый магик, процент риска, если надо - дополнительный код ТС, и получаете указатель на интерфейс Лиги. Сам интерфейс вот такой:

class CEALeagueTradeSysemI
{
public:
   // Виртуальные функции-обработчики событий. 
   // При получении интерфейса из библиотеки - эти функции должны вызываться в соответствующих обработчиках событий
   // В классе-интерфейсе объявляются функции-заглушки, которые в реальной работе вызваны не будут. 
   // (В идеале они должны быть чисто виртуальными, приравненными нулю, но такие функции не экспортируются из библиотеки)
   
   virtual int    TradeSystemOnInit() = 0;
   virtual void   TradeSystemOnDeinit(const int iReason) = 0;
   virtual void   TradeSystemOnTick() = 0;

   // Функция, возвращающая список магиков, работающих в Лиге ТС.
   // aulMagics - ccылка на массив, который заполняется найденными магиками.   
   // iLeagueDivision - номер дивизиона, магики которого должны быть возвращены.
   // (1 - Низший, 2 - Средний, 3 - Высший, любое другое значение - возвращаются все магики)
   // strSymbol - символ, магики которого должны быть возвращены (если NULL или неизвестный Лиге ТС - возвращаются все магики)   
   // Возвращает число найденных магиков, или WRONG_VALUE в случае ошибок
   virtual int GetMagics(ulong & aulMagics[],int iLeagueDivision = 3,string strSymbol = NULL) = 0; 
};

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

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

 
Andrei:

Пока логика класса не просматривается без поллитра)

Одна и та же функция вызывается в двух вариантах и еще и класс сам себя определяет дважды.

В общем баг в таком коде можно отлавливать годами))

Ну вопрос был о работе в классе с внешними данными. Это и было показано. Есть разные способы реализации.
А разный вызов/инициализация. Это уже отдельный вопрос.

 
Georgiy Merts:

Вот еще пример, из моей Лиги ТС:

Вот и весь эксперт, инкапсулирующий все 672 ТС.

...

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

Думаю что это двоякий вопрос - простому пользователю, который не открывал ни одну книжку по программированию зачем вообще интерфейс, он и эти простые действия может не понять. Ему надо мануал и кликнуть на галочках в настройках и всё. А программист я уверен не будет всерьёз работать с кодом, внутреннюю работу которого он не знает и сам не проверял.
 
ООП в программировании необходимо, на рынке - нет)
 
Martin Cheguevara:
ООП в программировании необходимо, на рынке - нет)

Странное высказывание... Оно применимо и к Форексу?

 

Постигшие ОOП на долго тут не задерживаются.Они уходят работать на крупный конторы/проекты за хорошую зп.

Хорошо разбираться в ОOП и сидеть тут на фрилансе-это трата своего времени и навыков. Всё-таки mql слишком узко-специализирован,

а задачи на фрилансе в большинстве своём однообразны и приметивны и со временем просто надоедает писать очередную сову по машке за копейки.

Я ни в коем случае ни хочу обидеть mql-сообщество или принизить достоинства языка mql.

Mql это хороший стартдля получения навыков общения с заказчиками, освоение ОOП , для перехода любителей в профи,

но НЕ как основной способ заработка для человека хорошо разбирающегося в программировании(в ОOП в частности).