Perguntas sobre OOP em MQL5 - página 83

 

Yaah... Como as pessoas estão confusas com const(((.

Para entender métodos com especificador const const

class CTest{
   int i;
public:
   CTest(int _i):i(_i){}
   int Get() const {return i;}
   int Get()   {return 2*i;}
};

void OnStart()
  {
   const CTest a(5);
   CTest b(8);
   Print(a.Get()); //5
   Print(b.Get()); //16
  }

Agora faça

   //int Get() const {return i;}

e depois fazer o inverso:

//   int Get()   {return 2*i;}

)))

 
Alexandr Andreev:

Também uma variante do mesmo código.


É com os contras.

E você está certo de que a entrada

Compare(CObject const *node,int const mode=0)

♪ você sempre alimentará ♪

CChartObjectRectangleX*

para escrever sem verificação?

return (  Time(1)-dynamic_cast<const ME*>(node).Time(1));

?

 
Alexandr Andreev:

a variante sem a constituição já que a classe base não tem referência aos parâmetros de entrada também funcionará corretamente, embora este estilo não seja muito inteligente

Não vai funcionar dessa forma. Você não pode alterar a assinatura no Comparar. É necessário principalmente para o método QuickSort, que está incluído no SB, para fazer a triagem regular.

Se você mudar a assinatura, não é uma anulação da função virtual, mas uma sobrecarga e é o método de chamada da classe base CObject onde retorna 0;

É claro que isto pode ser resolvido com embalagens (decoração) para recipientes, mas por que estes movimentos desnecessários, ou então não usam SB e escrevem tudo do zero.

 
Vladimir Simakov:

Parece ser o mesmo que o seu, só que com menos letras. Portanto, é uma questão de gosto, mas eu removi a variável extra (muito provavelmente, o compilador a teria removido como parte da otimização).

A respeito da minha verificação do !nó. Deve ser substituído por CheckPointer(node)==POINTER_INVALID, mas é uma sobrecarga - uma chamada de função. Mesmo que seja alinhada, ainda assim é pelo menos desreferenciada e verificada a bandeira de status. Se apenas biblioteca ou concreto, você escreveu um programa de comparação de métodos, melhor !nodo e em código para observar o ponteiro inválido. Se você é preguiçoso demais para ficar atento aos ponteiros ou se é uma biblioteca para os pontos fracos, apenas CheckPointer(node)==POINTER_INVALID.

Se você remover o especificador constante que você destacou, não poderá chamar estes métodos de um objeto constante.

UPD: a verificação destacada pode ser removida, como está nos chamados métodos.

Vladimir, só neste caso o CheckPointer é redundante. dynamic_cast retornará NULL para qualquer elenco falhado, inclusive se o ponteiro estiver quebrado. Por favor, me corrija se eu estiver errado. Testado há muito tempo, o teste demorou 5 segundos).

Mecanismo de funcionamento do CheckPointer (em palavras simples, não sou fluente em termos de baixo nível) - parece por ponteiro que tipo de objeto, dinâmico ou estático, se não podemos obter informações, significa POINTER_INVALIDO. Este pode ser o caso se o objeto dinâmico foi removido, outras situações que não conheço, ou carregou lixo para o ponteiro, mas deve verificar o compilador, se você não conseguir encontrar lacunas.

e dynamic_cast faz o mesmo, verificando também se o ponteiro pode ser lançado ao tipo desejado, ou seja, se é um ponteiro deste tipo ou uma classe infantil.

Se o ponteiro estiver quebrado, o dynamic_cast não detecta nada e retorna NULL.

É por isso que eu não usei o CheckPointer. Mas costumo usar este cheque em todos os lugares, fora do caminho do perigo. Afinal de contas, para encontrar um erro no software, que não cai, parece um pouco mais fácil).

E que tal não-constrição - em teoria podemos ter um método como GetRatingByAnyFormula() { m_rating01=Formula01(); return m_rating01;}

seria bastante inconveniente se não fosse usado na classificação imediatamente, ou seja, teríamos que contar primeiro a classificação e depois chamar a classificação por ela. Ou, como já foi dito, escreva sua própria SB a partir do zero).

 
Aleksey Mavrin:

Isto não é bom. A assinatura não pode ser alterada no Comparativo. É principalmente com o objetivo de fazer funcionar o QuickSort, o método de triagem regular incluído no SB.

Se você mudar a assinatura, não se sobrepõe à função virtual, mas se chama sobrecarga e método da classe base CObject, onde retorna 0;

É claro que isso pode ser resolvido com embalagens (decoração) para recipientes, mas por que esses movimentos desnecessários, ou não usam SB e escrevem tudo do zero?

A maneira mais correta é não escrever em µl

 
Aleksey Mavrin:

Vladimir, neste caso o CheckPointer é redundante. dynamic_cast retornará NULL para qualquer elenco mal sucedido, inclusive se o ponteiro estiver quebrado. Por favor, me corrija se eu estiver errado. Testado há muito tempo, o teste demorou 5 segundos).

Mecanismo de funcionamento do CheckPointer (em palavras simples, não sou fluente em termos de baixo nível) - parece por ponteiro que tipo de objeto, dinâmico ou estático, se não conseguimos obter informações, significa POINTER_INVALIDO. Este pode ser o caso se o objeto dinâmico foi removido, outras situações que não conheço, ou carregou lixo para o ponteiro, mas deve verificar o compilador, se você não conseguir encontrar lacunas.

e dynamic_cast faz o mesmo, verificando também se o ponteiro pode ser lançado ao tipo desejado, ou seja, se é um ponteiro deste tipo ou uma classe infantil.

Se o ponteiro estiver quebrado, o dynamic_cast não detecta nada e retorna NULL.

É por isso que eu não usei o CheckPointer. Mas costumo usar este cheque em todos os lugares, fora do caminho do perigo. Afinal de contas, para encontrar um erro no software, que não cai, parece um pouco mais fácil).

E quanto à não-constrição - em teoria podemos ter um método como GetRatingByAnyFormula() { m_rating01=Formula01(); return m_rating01;}

seria bastante inconveniente se não fosse usado na classificação imediatamente, ou seja, teríamos que contar primeiro a classificação e depois chamar a classificação por ela. Ou você pode escrever sua própria SB a partir do zero, como já mencionado).

  1. Os métodos de comparação são definidos como públicos, o que significa que qualquer underdog, não importa o quanto você tente explicar na especificação, empurrará para lá um descritor não-válido. É claro, se não for uma biblioteca, mas apenas para você mesmo, você não precisa fazê-lo.
  2. Eu não sei como funciona o CheckPointer, lá até . Mas em qualquer caso, é o relógio do processador e o acesso à memória (poderia facilmente se tornar também memória virtual).
  3. Sobre os métodos com o especificador const. Se você escreve uma biblioteca, deve ter sempre em mente que o objeto pode precisar de uma constante, portanto, nesses métodos, que não mudam o estado do objeto, como é desejável. Embora, até agora, para mim mesmo, eu não me incomode muito com isso.
  4. Escrevendo seu próprio sistema, esta é provavelmente a decisão certa. Isso é apenas uma perspectiva interessante na relação salário/trabalho ainda não é visível e, portanto, não será concluída, portanto, apenas para suas próprias necessidades).
 
Vladimir Simakov:

Sobre minha verificação de !nodo. Deve ser substituído por CheckPointer(node)==POINTER_INVALID, mas esta é uma chamada de função, de sobrecarga.

O problema não estará nas despesas gerais, mas no fato de que um ponteiro quebrado mudará a lógica do programa. Ou seja, em vez de detectar o problema, você o enterrará ainda mais fundo.

CheckPointer só deve ser usado para fins de depuração ou como uma implementação de um ponteiro fraco.

 
Vladimir Simakov:
  1. Os métodos comparativos são definidos como públicos, de modo que qualquer subserviente, não importa o quanto você lhe diga na especificação, empurrará um descritor inválido para lá (vamos chamar as coisas pelos nomes próprios). É claro, se não for uma biblioteca, mas apenas para você mesmo, você não precisa fazê-lo.
  2. Eu não sei como funciona o CheckPointer, lá até . Mas em qualquer caso, é o relógio do processador e o acesso à memória (poderia facilmente se tornar também memória virtual).
  3. Sobre os métodos com o especificador const. Se você escreve uma biblioteca, deve ter sempre em mente que o objeto pode precisar de uma constante, portanto, nesses métodos, que não mudam o estado do objeto, como é desejável. Até agora, no entanto, para mim, não me preocupo muito com isso.
  4. Escrevendo seu próprio sistema, esta é provavelmente a decisão certa. Isso é apenas uma perspectiva interessante na relação salário/trabalho ainda não é visível e, portanto, não haverá nada finalizado, portanto, apenas para suas próprias necessidades).

1. Nenhum argumento, mas o que eu estava dizendo é que você NÃO precisa de um CheckPointer (mesmo para underdogs), porque dynamic_cast NÃO pode retornar um ponteiro não-invalido, apenas NULL.

2. É até interessante, mas não posso pensar imediatamente em um exemplo que permita obter um ponteiro não-invalido, a não ser matar o objeto dinâmico ou a memória "suja" diretamente enquanto se trabalha nele.

Suponho que ainda existam tais meios, mas o mais provável é que todos eles se encontrem no plano de contornar as verificações do compilador.

3,4 De acordo.

P.S.

Devo ter me enganado em relação ao 1-st. O teste diz o contrário. Deve ser apenas uma impressão).

void OnStart()
  {
      CChartObjectRectangle *base = new CChartObjectRectangle();
      CChartObjectRectangleX *rect = new CChartObjectRectangleX();
       CChartObjectRectangle * dbase  ;
      const CChartObjectRectangleX *drect  ;
      Print("dbase= ",dbase, " NULL ? ",dbase==NULL," check? ",!dbase, " broken? ", EnumToString( CheckPointer(dbase) ));
      dbase=dynamic_cast< CChartObjectRectangle *>  (base);
      Print("dbase= ",dbase, " NULL ? ",dbase==NULL, " check? ",!dbase," broken? ", EnumToString( CheckPointer(dbase) ));
      delete base;
      Print("dbase= ",dbase, " NULL ? ",dbase==NULL," check? ",!dbase, " broken? ", EnumToString( CheckPointer(dbase) ));
      dbase=dynamic_cast< CChartObjectRectangle *>  (base);   
      Print("dbase= ",dbase, " NULL ? ",dbase==NULL," check? ",!dbase, " broken? ", EnumToString( CheckPointer(dbase) ));   
  }
 
É possível declarar uma matriz estática na seção de classe pública e rubricá-la no construtor? (como abaixo) (ou apenas elemento por elemento?)
 bool Mass[5] = { false, true, false, true, true };
 
Pavel Verveyko:
Uma matriz estática pode ser declarada na seção de classe pública e rubricada no construtor? (como abaixo) (ou apenas elemento por elemento?)

Você pode rubricar um array local e executar um ArrayCopy para o campo de array apropriado:

class A{
public:
   bool Mass[5];
   A(){
       bool mass_init[5] = { false, true, false, true, true };
       ArrayCopy(Mass, mass_init);
   }
};