Perguntas sobre OOP em MQL5 - página 3

 

Se todos os botões funcionam com apenas uma linha de cada vez, então crie uma variável estática na classe de botões para referenciar a linha. Mas somente isto não é razoável, porque limita as possibilidades de classe de botões - não se pode criar dois pares de botões para trabalhar com duas linhas em paralelo.

E a solução correta para o problema é elementar - escrever uma função, a referência à linha é passada para a função, e a função passa esta referência para os objetos de botão desejados. Você não precisa procurar nenhuma maravilha no OOP.

Ou, você pode escrever uma classe que cria dois botões.

 
Dmitry Fedoseev:

Se todos os botões funcionam com apenas uma linha de cada vez, então crie uma variável estática na classe de botões para referenciar a linha. Mas só isso não faz sentido, porque limita o que a classe de botões pode fazer - você não pode criar dois pares de botões para trabalhar com duas linhas em paralelo.

Sim, eu tenho quatro pares de botões e quatro linhas, então eu descartei a variável estática como opção também.

E a solução correta para o problema é elementar: escrever uma função, o link para a linha é passado para a função, e este link é passado para os objetos de botão desejados na função. Você não precisa procurar nenhum milagre no OOP.

Bem, ou escrever uma classe que cria dois botões.

E eu acreditava nos milagres do OOP ).

Obrigado por estas opções, vou pensar em qual delas seria a mais adequada para mim.

 
Vasiliy Pushkaryov:

Ajude-me a resolver um problema. Há dois botões e uma linha. Um botão, quando pressionado, coloca a linha em modo de edição, e quando liberado, apaga a linha. O segundo botão, quando clicado, conserta a linha e, quando clicado, volta a colocá-la no modo de edição. Cada botão pode mudar a cor e algumas outras propriedades do objeto Linha. O objeto "Linha" é definido globalmente. É possível passar uma referência ao objeto "Linha" para cada botão imediatamente após a criação dos botões, para que quando você manipula a variável de referência dentro dos objetos "Botão", todas as mudanças sejam lembradas no objeto global "Linha".

Eu esbocei um script simplificado abaixo, em vez de pressionar um botão - função adição(), que incrementa o contador do objeto "Linha". Entendo que você pode passar o objeto "Linha" como um argumento de função por referência, mas apenas na versão de trabalho, existem várias funções desse tipo, portanto, gostaria de passar a referência no início uma vez. Isto é, é possível fazer o Btn1.addition() ou Btn2.addition() aumentar o gLine.count ?

É assim que eu estou fazendo agora:


talvez esta seja a maneira de fazer isso?

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

talvez seja assim que deve ser?

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

Sim Igor, é isso mesmo, muito obrigado.

Ainda estou "soluçando" em ponteiros, portanto sua solução me ajudará em minha tarefa atual e na compreensão de comousar ponteiros.

Obrigado por seu feedback.

 
Igor Makanu:

talvez seja assim que deve ser?

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

E por que você usa GetPointer(gLine) se você mesmo declarou gLine como um ponteiro? )))

Também é preciso criar o objeto CLine ao declará-lo:

CLine* gLine=nova CLine;

Botão e linha também precisam ser inicializados na fase de inicialização do botão.

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

Por que você usa GetPointer(gLine) se você mesmo declarou a gLine como um ponteiro? )))

A formação de um objeto CLine é também uma tarefa urgente ao declará-lo:

CLine* gLine=nova CLine;

Botão e linha também devem ser inicializados na fase de inicialização do botão.

Foi à noite, não está claro porque o escrevi dessa maneira. Na verdade eu estava dormindo, o Skype me acordou, e simplesmente pulou o fórum ))))

E sério, meu exemplo é um tutorial, eu não o verifiquei, talvez eu tenha ressegurado em um nível subconsciente, eu não entendo completamente o que é um indicador MQL, obviamente não funciona como nos indicadores C++.

Tenho tentado descobrir, mas ainda não descobri como funcionam os ponteiros como parâmetro para a funçãohttps://www.mql5.com/ru/forum/1111/page2470#comment_11796309- passo um ponteiro para a função lá, mas na verdade recebo uma nova cópia do ponteiro criado

SZY: Não consigo descobrir qual é o escopo dos indicadores MQL-pointers, também pergunteihttps://www.mql5.com/ru/forum/1111/page2488#comment_12154218.... Parece que não entendo quais casos têm alcance local e quais têm alcance global ... Por isso, estou trabalhando com os MQL-pointers por experiência científica (((


Vasiliy Pushkaryov:

Sim, Igor, é isso mesmo, muito obrigado.

Ainda estou "nadando" em dicas, é por isso que sua solução será muito útil para mim em minha tarefa atual e em um maior entendimento de como usar as dicas.

Obrigado por seu feedback.

Por favor! com MQL-pointers apenas prática ajudará aqui, eles têm comportamento peculiar, como@Vladimir Simakov escreveu seu problema é mais provável que seja resolvido escrevendo um construtor com parâmetro - eu normalmente faço isso, de um ponto de vista abstrato? - Não é correto, mas é conveniente e sempre funciona corretamente - e o compilador não deixará que você se esqueça de amarrar o ponteiro.

if(CheckPointer(m_Line)==POINTER_DYNAMIC)

esta verificação pode ser eliminada porque de qualquer forma você salvará o ponteiro ao chamar o construtor

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

Uau, afinal a tarefa não era esperar que dois objetos passassem um ponteiro para uma linha ao mesmo tempo. Tratava-se, na verdade, de passar um ponteiro. Quem teria pensado?

Você não precisa criar o objeto através do novo para poder passar um ponteiro em algum lugar. Mas a classe para a qual o ponteiro é passado deve ter uma variável ponteiro (com um asterisco *).

 
Igor Makanu:

era de noite, está escuro - por que escrevi assim... Eu estava realmente dormindo, o Skype no meu telefone me despertou, então eu folheei o fórum de passagem ))))

E sério, meu exemplo é um tutorial, eu não o verifiquei, talvez eu tenha ressegurado em um nível subconsciente, eu não entendo completamente o que é um indicador MQL, obviamente não funciona como nos indicadores C++.

Tenho tentado descobrir, mas ainda não descobri como funcionam os ponteiros como parâmetro para a funçãohttps://www.mql5.com/ru/forum/1111/page2470#comment_11796309- passo um ponteiro para a função lá, mas na verdade recebo uma nova cópia do ponteiro criado

SZY: Não consigo descobrir qual é o escopo dos indicadores MQL-pointers, também pergunteihttps://www.mql5.com/ru/forum/1111/page2488#comment_12154218.... Parece que não entendo quais casos têm alcance local e quais têm alcance global ... Em suma, estou trabalhando com os MQL-pointers usando o método de experimento científico (((

No primeiro caso, tudo é simples. Você realmente cria um novo objeto dinâmico na pilha, e isso é tudo. Você tem que passá-lo para o ...(CObj* &jbj,...

E no segundo caso, você tem que fazê-lo:

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

Para o primeiro caso, é simples. Você realmente cria um novo objeto dinâmico na pilha e é isso. Você deve passá-lo para o ...(CObj* &jbj,...

E, no segundo caso, você deve:

Vou verificar hoje à noite, a referência não dá muitas informações sobre o uso &.

Obrigado!

 
O ponteiro também pode ser passado por não-referência - sem &.
Razão: