Вопросы по ООП в MQL5 - страница 3

 

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

А правильное решение задачи элементарно  - написать функцию, в функцию передается ссылка на линию, а в функции эта ссылка передается нужным объектам кнопки. Не надо никаких чудес выискивать в ООП.

Ну или написать класс, создающий две кнопки.

 
Dmitry Fedoseev:

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

Да, у меня четыре пары кнопок и четыре линии, поэтому статическую переменную тоже откинул, как вариант.

А правильное решение задачи элементарно  - написать функцию, в функцию передается ссылка на линию, а в функции эта ссылка передается нужным объектам кнопки. Не надо никаких чудес выискивать в ООП.

Ну или написать класс, создающий две кнопки.

А я верил в чудеса ООП ).

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

 
Vasiliy Pushkaryov:

Помогите решить задачу. Есть две кнопки и линия. Одна кнопка при нажатии выводит линию в режиме редактирования, при отжатии удаляет линию. Вторая кнопка при нажатии закрепляет ее, при отжатии снова переводит в режим редактирования. Каждая кнопка может поменять цвет и некоторые другие свойства объекта "Линия". Объект "Линия" задается на глобальном уровне. Можно ли сразу после создания кнопок передать в каждую кнопку ссылку на объект "Линия" таким образом, чтобы при манипуляциях со ссылочной переменной внутри объектов "Кнопка" все изменения запоминались в глобальном объекте "Линия".

Ниже я набросал упрощенный скрипт, вместо нажатия кнопки - функция addition(), которая увеличивает счетчик объекта "Линия". Я понимаю, что можно передавать объект "Линия" как аргумент функции по ссылке, но просто в рабочем варианте, таких функций несколько, поэтому хотелось бы передать ссылку в самом начале один раз. Т.е. как-то можно сделать, чтобы при вызове Btn1.addition() или Btn2.addition() происходило увеличение счетчика gLine.count ?

У меня сейчас так происходит:


может так нужно?

//+------------------------------------------------------------------+
class CLine
  {
public:
   int               count;
                     CLine(void){count=0;};
                    ~CLine(void){};
  };
//+------------------------------------------------------------------+
class CMyButton
  {
private:
public:
   CLine            *m_Line;
                     CMyButton(void):m_Line(NULL){};
                    ~CMyButton(void){};

   void bind(CLine *aLine) {m_Line=aLine;}
   void addition() {if(CheckPointer(m_Line)==POINTER_DYNAMIC){++m_Line.count;}}
  };


CMyButton  Btn1;
CMyButton  Btn2;

CLine *gLine;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   gLine = new CLine;
   Btn1.bind(GetPointer(gLine));
   Btn2.bind(GetPointer(gLine));
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   Print("Line.count=", gLine.count);
   Btn1.addition();
   Print("Line.count=", gLine.count, "  Btn1.m_Line.count=", Btn1.m_Line.count);
   Btn2.addition();
   Print("Line.count=", gLine.count, "  Btn2.m_Line.count=", Btn2.m_Line.count);
   Btn1.addition();
   Print("Line.count=", gLine.count, "  Btn1.m_Line.count=", Btn1.m_Line.count);
   Btn2.addition();
   Print("Line.count=", gLine.count, "  Btn2.m_Line.count=", Btn2.m_Line.count);
  }
//+------------------------------------------------------------------+

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=196

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=197  Btn1.m_Line.count=197

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=198  Btn2.m_Line.count=198

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=199  Btn1.m_Line.count=199

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=200  Btn2.m_Line.count=200

2019.07.04 00:44:31.856 1 (EURUSD,H1) Line.count=200

2019.07.04 00:44:31.856 1 (EURUSD,H1) Line.count=201  Btn1.m_Line.count=201

 
Igor Makanu:

может так нужно?

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=196

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=197  Btn1.m_Line.count=197

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=198  Btn2.m_Line.count=198

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=199  Btn1.m_Line.count=199

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=200  Btn2.m_Line.count=200

2019.07.04 00:44:31.856 1 (EURUSD,H1) Line.count=200

2019.07.04 00:44:31.856 1 (EURUSD,H1) Line.count=201  Btn1.m_Line.count=201

Да, Игорь, оно самое, спасибо огромное.

Я пока в указателях еще немного "плаваю", поэтому Ваше решение очень поможет мне и в текущей задаче и в дальнейшем понимании, как можно использовать указатели.

Благодарю, что откликнулись.

 
Igor Makanu:

может так нужно?

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=196

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=197  Btn1.m_Line.count=197

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=198  Btn2.m_Line.count=198

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=199  Btn1.m_Line.count=199

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=200  Btn2.m_Line.count=200

2019.07.04 00:44:31.856 1 (EURUSD,H1) Line.count=200

2019.07.04 00:44:31.856 1 (EURUSD,H1) Line.count=201  Btn1.m_Line.count=201

А зачем Вы используете GetPointer(gLine), если сами же gLine указателем объявили? )))

Да и создать объект CLine напрашивается еще при объявлении:

CLine* gLine=new CLine;

Cвязать кнопку с линией тоже напрашивается на этапе инициализации кнопки.

...
                CMyButton(CLine* line):m_Line(!CheckPointer(line)?NULL:line){};
...
CLine* gLine=new CLine;
CMyButton  Btn1(gLine);
 
Vladimir Simakov:

А зачем Вы используете GetPointer(gLine), если сами же gLine указателем объявили? )))

Да и создать объект CLine напрашивается еще при объявлении:

CLine* gLine=new CLine;

Cвязать кнопку с линией тоже напрашивается на этапе инициализации кнопки.

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

а если серьезно, то пример мой учебный, проверять его я особо не проверял, видимо на подсознательном уровне перестраховался, я не до конца понимаю, что за сущность MQL-указатель, однозначно он работает не как в С++ указатели

вот пытался разобраться, но не победил как работают указатели в качестве параметра функции https://www.mql5.com/ru/forum/1111/page2470#comment_11796309    -  там передаю в функцию указатель, а реально у меня новая копия указателя создается

ЗЫ: с областями видимости MQL-указателей я не могу разобраться, вот еще спрашивал https://www.mql5.com/ru/forum/1111/page2488#comment_12154218  .... никак не пойму, в каких случаях у указателя локальная область видимости, а где глобальная... в общем методом научного тыка работаю с MQL-указателями (((


Vasiliy Pushkaryov:

Да, Игорь, оно самое, спасибо огромное.

Я пока в указателях еще немного "плаваю", поэтому Ваше решение очень поможет мне и в текущей задаче и в дальнейшем понимании, как можно использовать указатели.

Благодарю, что откликнулись.

пожалуйста! с MQL-указателями тут только практика поможет, поведение у них своеобразное, как написал @Vladimir Simakov Вашу задачу скорее всего лучше решать путем написания конструктора с параметром - я так обычно делаю, с точки зрения абстракций? - это не правильно, зато удобно и работает всегда корректно - да и компилятор не даст забыть сделать привязку указателя, я проверяю через 

if(CheckPointer(m_Line)==POINTER_DYNAMIC) 

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

Ошибки, баги, вопросы
Ошибки, баги, вопросы
  • 2019.05.22
  • www.mql5.com
Общее обсуждение: Ошибки, баги, вопросы
 

Ух ты, оказывается задача была не в том, что бы двум объектам одновременно переждать указатель на линию. А вообще - в том, что бы передать указатель. Кто бы мог подумать.

Что бы иметь возможность куда-то передать указатель, вовсе нет необходимости создавать объект через new. А вот в классе, в который указатель передается, должна быть переменная-указатель (со звездочкой *). 

 
Igor Makanu:

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

а если серьезно, то пример мой учебный, проверять его я особо не проверял, видимо на подсознательном уровне перестраховался, я не до конца понимаю, что за сущность MQL-указатель, однозначно он работает не как в С++ указатели

вот пытался разобраться, но не победил как работают указатели в качестве параметра функции https://www.mql5.com/ru/forum/1111/page2470#comment_11796309    -  там передаю в функцию указатель, а реально у меня новая копия указателя создается

ЗЫ: с областями видимости MQL-указателей я не могу разобраться, вот еще спрашивал https://www.mql5.com/ru/forum/1111/page2488#comment_12154218  .... никак не пойму, в каких случаях у указателя локальная область видимости, а где глобальная... в общем методом научного тыка работаю с MQL-указателями (((

По первому случаю все просто. Вы реально создаете на стеке новый динамический объект и все. Надо передавать в функцию ...(CObj* &jbj,...

А во втором случае надо:

void  AddValue (T &value)  { Tptr  = value; mlist.Add(Tptr);       }
 
Vladimir Simakov:

По первому случаю все просто. Вы реально создаете на стеке новый динамический объект и все. Надо передавать в функцию ...(CObj* &jbj,...

А во втором случае надо:

вечером проверю, информации по использованию &  толком нет в справке, наверное Вы правы

Спасибо!

 
Указатель можно и не по ссылке передавать - без &.
Причина обращения: