Erros, bugs, perguntas - página 1206

 
stringo:

É isso mesmo. É dada prioridade à concorrência exacta. E é realmente correcto.

Porque é que precisa de tal unificação? Unificação do processamento de programas concebidos de forma incorrecta

A unificação é necessária para que o mesmo código funcione igualmente com C++ e MQL. Em C++, esta ordem é feita (!) por uma razão (caso contrário há ambiguidades em algum momento). Inicialmente eu pensava que o compilador C++ tinha ilógico e/ou mesmo um bug, mas agora estou inclinado a acreditar que existem razões objectivas para tal abordagem. Aqui está um exemplo em MQL, que mostra que X::: g é uma correspondência completa, mas Y::g é chamado de qualquer forma - como em C++, o que contradiz o exemplo anterior https://www.mql5.com/ru/forum/1111/page1223#comment_1074757

class A {};
class B : public A {};
class C : public B {};
class X {
public:
        virtual int g( C* c1, C* c2 ) { return ( 1 ); } //полное совпадение здесь
        virtual int g( C* c,  B* b )  { return ( 2 ); }
};
class Y : public C { //здесь ошибся, должно быть public : X
public:
        virtual int g( A* a, B* b ) { return ( 3 ); }
};
void OnStart()
{
        C* c = new C;
        Y* y = new Y;
        Print( y.g( c, c ));
}

Resultado: 3

Acontece que C++ tem uma ordem "ilógica" mas inequívoca, enquanto o MQL tem uma ordem aleatória - se houver uma correspondência exacta de tipos, uma classe base é chamada num caso e uma classe derivada no outro

 
A100:

A unificação é necessária para que o mesmo código funcione igualmente com C++ e MQL. Em C++, esta ordem é feita (!) por uma razão. Inicialmente eu pensava que o compilador C++ tinha ilógico e/ou mesmo um bug, mas agora estou inclinado a acreditar que existe uma razão objectiva para tal abordagem. Aqui está um exemplo no MQL que mostra que X::: g é uma correspondência completa, mas Y::g é chamado de qualquer forma - como em C++, o que contradiz o exemplo anterior

Resultado: 3

Acontece que o C++ tem uma ordem "ilógica" mas inequívoca, enquanto o MQL tem uma ordem aleatória - com a concordância exacta dos tipos, a classe base é chamada num caso e a classe derivada no outro

De que implementação C++ está a falar exactamente? Quão bem corresponde esta implementação à norma C++. O que diz a norma C++ sobre a escolha de funções sobrecarregadas?

Na verdade, a sobrecarga da função que descreve é uma consequência de uma concepção incorrecta.

A portabilidade do código fonte é um mito. Apenas o programa de teste funciona da mesma forma em diferentes ambientes C++. O programa real (estamos a falar de milhares de linhas de código com um valor de aplicação real) funcionará de forma diferente, pelo menos em alguns aspectos em ambientes diferentes. E não há nada a falar em unificar MQL com C++ - é um desperdício do pool genético...

 
A100:

A unificação é necessária para que o mesmo código funcione igualmente com C++ e MQL. Em C++, esta ordem é feita (!) por uma razão (caso contrário há ambiguidades em algum momento). Inicialmente eu pensava que o compilador C++ tinha ilógico e/ou mesmo um bug, mas agora estou inclinado a acreditar que existem razões objectivas para tal abordagem. Aqui está um exemplo em MQL, que mostra que X::: g é uma correspondência completa, mas Y::g é chamado de qualquer forma - como em C++, o que contradiz o exemplo anterior https://www.mql5.com/ru/forum/1111/page1223#comment_1074757

Resultado: 3

Acontece que C++ tem uma ordem "ilógica" mas inequívoca e MQL tem uma ordem aleatória - em caso de correspondência exacta do tipo, uma classe base é chamada num caso e uma classe derivada num outro caso

Parece estar enganado neste exemplo, se a classe Y for herdada de X e não de C, então o comportamento seria o mesmo que no exemplo anterior.
 
stringo:

O que diz a norma C++ sobre a ordem de selecção das funções sobrecarregadas?

Para citar Strawstrup: "C++ requer uma correspondência exacta do tipo entre a função virtual na classe base e a função substituída na classe derivada".

Analisei agora a questão e cheguei à conclusão de que C++ está correcto. Em ambos os exemplos acima, g() da classe derivada esconde (em vez de substitutos) g() da classe base. E o mecanismo de virtualidade só é activado quando a substituição tem lugar, e a substituição requer uma correspondência exacta do tipo (excepto para o tipo de retorno). Só a exactidão do tipo de retorno pode depender da aplicação específica.

 
mql5:
Parece estar enganado neste exemplo, se a classe Y for herdada de X em vez de C, o comportamento seria o mesmo que o exemplo anterior.

Sim, enganei-me aqui, pelo que se verifica que tanto o C++ como o MQL têm ordens de substituição e ocultação inequívocas, mas diferentes. Por favor ver os meus argumentos no post anterior sobre a diferença entre substituição e ocultação

O facto de C++ gerar um aviso ao esconder-se diz-lhe que esta ordem é escolhida intencionalmente

class A {};
class B : public A {};

class X {
public:
        virtual int g( A* a )
        virtual int f( B* a )
};
class Y : public X {
public:
        virtual int g( A* a ) //подмена  X::g
        virtual int f( A* a ) //сокрытие X::f
};
 
A100:

Sim, enganei-me aqui, pelo que se verifica que tanto o C++ como o MQL têm ordens de substituição e ocultação inequívocas, mas diferentes. Por favor veja os meus argumentos no post anterior sobre a diferença entre substituição e ocultação

O facto de C++ gerar um aviso ao esconder-se indica que esta ordem é escolhida intencionalmente

O compilador MQL ao procurar um método (função) não considera passar para um pai como fundição, como parece fazer com o C++ da MS, por exemplo.

Obrigado pelo correio, discutiremos(pensem nisso).

 
mql5:
O compilador MQL ao procurar um método (função) não considera passar para um pai como fundição, como parece fazer com a MS C++, por exemplo.

Obrigado pela mensagem, discutiremos(pensem sobre isso).

Note-se que não só da EM - Utilizei Borland C++ 5.5.1

Stroustrup escreve que, caso contrário, pode haver consequências desagradáveis relacionadas com "ir para além do fim do objecto de classe".

 
A100:

Para citar Strawstrup: "C++ requer uma correspondência exacta do tipo entre uma função virtual numa classe base e uma função substituta numa classe derivada".

Analisei agora a questão e cheguei à conclusão de que C++ está correcto. Em ambos os exemplos acima, g() da classe derivada esconde (em vez de substitutos) g() da classe base. E o mecanismo de virtualidade só é activado quando a substituição tem lugar, e a substituição requer uma correspondência exacta do tipo (excepto para o tipo de retorno). Apenas a exactidão do tipo de retorno pode depender da aplicação específica.

Espere um minuto, espere um minuto. Estamos a falar de funções de sobrecarga com parâmetros diferentes.

As funções virtuais, por outro lado, têm sempre parâmetros do mesmo tipo. As funções virtuais estão fora do âmbito desta discussão

 
A100:

Note-se que não só da EM - Utilizei Borland C++ 5.5.1

Stroustrup escreve que, caso contrário, pode haver consequências desagradáveis relacionadas com "ultrapassar o fim do objecto de classe".

Já discutimos isto; não vamos alterar o comportamento do compilador MQL - é um "pau de dois gumes". Deixem-me explicar.

O problema só é relevante quando são feitas modificações nas aulas prontas (num programa de trabalho).
Depois de o pai ter uma função mais adequada, o programa deixará subitamente de funcionar, porque em vez do método do descendente, o método do pai foi chamado.
Bem, se alterarmos o comportamento do MQL, então uma situação semelhante pode ocorrer - ao adicionar um novo método ao descendente, em vez da função de parentalidade (sem fundição de parâmetros), o método descendente é chamado, e com fundição de parâmetros, e o programa deixa de funcionar novamente.

Assim, nenhum outro problema para além da compatibilidade com C++ será resolvido, além disso, a mudança de comportamento do compilador afectará os programas MQL existentes.
 

Так как переменные типа структур и простых типов не имеют указателей, то применять к ним функцию GetPointer() запрещено.

É também proibidopassar um ponteirocomo argumento para uma função (qual ?? ??GetPointer ou qualquer ?).Em todos estes casos, o compilador irá reportar um erro.

Citação a partir da documentação.

class A{
public:
   void operator= (const A* from){
      if (GetPointer(this) == GetPointer(from))      // а тут я передаю и все ок
         Alert(1);                                  // резутат 1  из за того что передаю this
      else
         Alert(2);
   }
};

class B : public A{
public:
   void operator= (const B& from){  
      if (GetPointer(this) == GetPointer(from))
         return;
      operator=((A*)(GetPointer(this)));
   }
};
  B b;
   B bb;                        // забыл написать создание объектов и вызов функции.
   b = bb;

Já percebi porque não é repreensão por alertas - a culpa é minha de ter passado um ponteiro errado para uma função.