Questions on OOP in MQL5 - page 3

 

If all buttons work with only one line at a time, then create a static variable in the button class to reference the line. But only this is not reasonable, because it limits possibilities of button class - you can't create two pairs of buttons to work with two lines in parallel.

And the correct solution to the problem is elementary - write a function, the reference to the line is passed to the function, and the function passes this reference to the desired button objects. You don't need to seek out any wonders in OOP.

Or, you can write a class that creates two buttons.

 
Dmitry Fedoseev:

If all buttons work with only one line at a time, then create a static variable in the button class to reference the line. But that alone doesn't make sense, because it limits what the button class can do - you can't create two pairs of buttons to work with two lines in parallel.

Yes, I have four pairs of buttons and four lines, so I discarded static variable as an option, too.

And the correct solution to the problem is elementary: write a function, the link to the line is passed to the function, and this link is passed to the desired button objects in the function. You don't need to seek out any miracles in OOP.

Well, or write a class that creates two buttons.

And I believed in the miracles of OOP ).

Thanks for these options, I'll think about which one would suit me best.

 
Vasiliy Pushkaryov:

Help me solve a problem. There are two buttons and a line. One button, when pressed, puts the line in edit mode, and when released, deletes the line. The second button, when clicked, fixes the line, and when clicked, puts it back in edit mode. Each button can change the colour and some other properties of the Line object. The "Line" object is defined globally. Is it possible to pass a reference to the "Line" object to each button immediately after creating buttons so that when you manipulate the reference variable inside the "Button" objects, all changes are remembered in the global "Line" object.

I've sketched a simplified script below, instead of pressing a button - addition() function, which increments the counter of "Line" object. I understand that you can pass the "Line" object as a function argument by reference, but just in the working version, there are several such functions, so I would like to pass the reference at the beginning once. I.e. is it possible to make Btn1.addition() or Btn2.addition() increase the gLine.count ?

That's how I'm doing it right now:


maybe this is the way to do it?

//+------------------------------------------------------------------+
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:

maybe this is how it should be?

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

Yes Igor, that's it, thank you very much.

I'm still "floundering" in pointers, therefore your solution will help me in my current task and in further understanding howto use pointers.

Thank you for your feedback.

 
Igor Makanu:

maybe this is how it should be?

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

And why do you use GetPointer(gLine) if you yourself declared gLine as a pointer? )))

One also needs to create the CLine object when declaring it:

CLine* gLine=new CLine;

Button and line also need to be initialized at the stage of button initialization.

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

Why do you use GetPointer(gLine) if you yourself declared gLine as a pointer? )))

Forming a CLine object is also an urgent task when declaring it:

CLine* gLine=new CLine;

Button and line should also be initialized at the stage of button initialization.

It was at night, it's not clear why I wrote it that way... I was actually sleeping, Skype woke me up, so I just skipped around the forum )))

And seriously, my example is a tutorial, I haven't checked it, maybe I overchecked on a subconscious level, I don't fully understand what an MQL-pointer is, it obviously does not work like in C++ pointers

I've been trying to figure it out, but I haven't figure out how pointers work as a parameter for the functionhttps://www.mql5.com/ru/forum/1111/page2470#comment_11796309- I pass a pointer to the function there, but in fact I get a new copy of the pointer created

SZY: I can't figure out what scope MQL-pointers have, I also askedhttps://www.mql5.com/ru/forum/1111/page2488#comment_12154218.... I still don't understand which cases have local scope and which have global scope ... So I'm working with MQL-pointers by scientific experiment (((


Vasiliy Pushkaryov:

Yes, Igor, that's it, thanks a lot.

I'm still "swimming" in pointers, that's why your solution will be very helpful for me in my current task and in further understanding of how to use pointers.

Thank you for your feedback.

Please! With MQL-pointers only practice will help here, they have peculiar behavior, as@Vladimir Simakov wrote your problem is most likely to be solved by writing a constructor with parameter - I usually do so, from abstract point of view? - It is not correct, but it is convenient and always works correctly - and the compiler will not let you forget to bind the pointer.

if(CheckPointer(m_Line)==POINTER_DYNAMIC)

this check can be eliminated because you will anyway save the pointer when calling the constructor

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

Wow, it turns out the task wasn't to wait for two objects to pass a pointer to a line at the same time. It was actually about passing a pointer. Who would have thought?

You don't need to create the object through new to be able to pass a pointer somewhere. But the class to which the pointer is passed must have a pointer variable (with an asterisk *).

 
Igor Makanu:

it was at night, it's dark - why I wrote it that way... I was actually asleep, Skype on my phone woke me up, so I skimmed the forum in passing )))

And seriously, my example is a tutorial, I haven't checked it, perhaps I've reinsured on a subconscious level, I don't fully understand what an MQL-pointer is, it obviously does not work like in C++ pointers

I've been trying to figure it out, but I haven't figure out how pointers work as a parameter for the functionhttps://www.mql5.com/ru/forum/1111/page2470#comment_11796309- I pass a pointer to the function there, but in fact I get a new copy of the pointer created

SZY: I can't figure out what scope MQL-pointers have, I also askedhttps://www.mql5.com/ru/forum/1111/page2488#comment_12154218.... I still don't understand which cases have local scope and which have global scope ... All in all, I'm working with MQL-pointers using the method of scientific experiment (((

Everything is simple in the first case. You actually create a new dynamic object on the stack, and that's it. You have to pass it into the ...(CObj* &jbj,...

And in the second case, you have to:

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

For the first case, it's simple. You actually create a new dynamic object on the stack and that's it. You should pass it into the ...(CObj* &jbj,...

And in the second case you should:

I will check it tonight, the reference doesn't give much information on using &.

Thank you!

 
The pointer can also be passed by non-reference - without &.
Reason: