MQL5 O compilador não faz distinção entre uma classe e um ponteiro para ela - página 5

 
O sinal = copia a área de memória de um objeto para a área de memória de outro objeto. Todos os objetos permanecem onde estavam.
 
Vladimir Simakov:
Não há maneira de acionar. É um puro vazamento de memória.

Faça-o de modo que possa ser convocado.

 

A propósito, senhores desenvolvedores, é melhor consertarmos isto. Afinal, novo retorna um ponteiro, então acrescente uma verificação que na outra ponta = também um ponteiro, remova a conversão implícita (A) novo A(); como eu entendo - isto é o que acontece.

 
Vladimir Simakov:

A propósito, caros desenvolvedores, é melhor eu consertar isto. Afinal, o novo realmente retorna um ponteiro, então acrescente uma verificação de que a outra ponta = também um ponteiro, remova a conversão implícita (A) novo A(); como eu entendi - isto é o que acontece.

Há uma chamada para este operador

Fórum sobre comércio, sistemas automatizados de comércio e testes estratégicos

O Compilador MQL5 não faz distinção entre uma classe e um ponteiro

fxsaber, 2019.01.10 06:36

Desde quando estes são definidos (pergunta para desenvolvedores)

void A::operator =( const A& );
void A::operator =( const A* );

E como eles funcionam? O seguinte código compilado parece ilusório

    A* b = NULL;    
    m_A[1] = b;    


Grosseiramente falando, parece assim

class A
{
public:
    int iValue;
    
    void operator =( const A* Ptr )
    {
      Print(__FUNCSIG__);
      
      this.iValue = Ptr.iValue;
    }
};
//......................
A m_A[2];

void OnStart()
{
A a;

    m_A[0] =a; 
    m_A[1] = new A();
}
 
fxsaber:

Lá se vai a chamada para este operador


Grosseiramente falando, parece assim

Sim, eu entendo. Não é um mau ancinho. A propósito, esta sobrecarga do operador = não existe em C++, a VS jura.
 

Antes de fazer uma confusão, seria bom saber que na MQL todos os seus indicadores de vida foram implicitamente lançados a objetos (desreferenciados), é conveniente e todos se acostumaram a isso. Em vez de a()->b()->c()->d() de difícil leitura, você pode escrever no formato OOP habitual: a().b().c().d(), e fazer menos transformações desnecessárias ao passar para funções. E agora, por causa da insatisfação de alguém, você muda tudo?

 
Alexey Navoykov:

Antes de fazer uma confusão sobre isso, seria bom saber que na MQL todos os seus indicadores de vida foram fundidos implicitamente (desreferenciados) a objetos, é conveniente e todos se acostumaram a isso. Em vez de a()->b()->c()->d() de difícil leitura, você pode escrever no formato OOP habitual: a().b().c().d(), e fazer menos transformações desnecessárias ao passar para funções. E agora, por causa da insatisfação de alguém, você muda tudo?

Não se trata de fundição. Você não se envolveu nisso.

 

Se formos guiados pelo protótipo declarado de MQL - C+++.

Em C++, o novo operador retorna um ponteiro, respectivamente, se m_A for um conjunto de objetos:

m_A[1] = new A();

haveria aqui um erro de tipo.

Esta é a linha que o compilador teria pulado:

m_A[1] = *( new A() );

Mas isso causaria um vazamento de memória.


Seria bom se a MQL tivesse o mesmo comportamento.

 
Alexey Navoykov:

Antes de começar a fazer alarde sobre isso, você deve saber que na MQL todas as suas indicações de vida foram implicitamente lançadas a objetos (desreferenciados), é conveniente e todos se acostumaram a isso. Em vez de a()->b()->c()->d() , você pode escrever no formato OOP habitual: a().b().c().d(), e menos transformações desnecessárias no processo de passagem às funções. E agora, por causa da insatisfação de alguém, você muda tudo?

E se você entrar em detalhes com alguns exemplos simples.

A a;

// 'a' ожидает объект
 
a = new A(); // а ему дают указатель, ведь можно же

// что в MQL равнозначно?
a = *(A*) new A();

Como resultado, temos

1. a' obtém uma cópia do objeto criado, o ponteiro para o novo objeto criado se perde

2) O que acontecerá com 'a' se um novo objeto não for criado/alocado em memória?

O segundo caso (ao contrário)

A* a; // глобальный указатель - 'a' ожидает указатель на объект

// далее всё происходит внутри некой функции
A b; // создаем второй в стеке (ну типа в стеке, не суть)

a =b;
// т.е. тут объект "неявно кастится" к указателю?)
a = &b;

Após sair da função, o objeto 'b' deve ser destruído como um objeto local.

ao que se referirá "a" então?

2. ou o operador da cópia ainda funcionará e 'b' será copiado pelo ponteiro 'a' ? e se 'a' não tiver sido definido antes ?

 
SemenTalonov:

O segundo caso (ao contrário)

A* a; // глобальный указатель - 'a' ожидает указатель на объект

// далее всё происходит внутри некой функции
A b; // создаем второй в стеке (ну типа в стеке, не суть)

a =b;
// т.е. тут объект "неявно кастится" к указателю?)


Aqui é vice-versa - um ponteiro a é implicitamente fundido em um objeto (desreferenciado) e então operador= é aplicado a ele. fxsaber também o mencionou ontem.

Embora logicamente não contradiga as regras MQL (já que chamar operador= é equivalente a chamar qualquer outro método de objeto), leva a uma compreensão ambígua de tal código e a erros difíceis de encontrar. E isto diz respeito não somente ao operador= mas == e != também, pelo menos. Talvez tal fundição deva ser proibida também para outros operadores, pois em C++ você pode aplicar aos operadores: +-<>[].

O breve veredicto é o seguinte: ao aplicar a um ponteiro operadores que são permitidos para apontadores em C++, desautorize uma fundição implícita deste ponteiro a um objeto. Correspondentemente, o exemplo acima causaria um erro de compilação.