MQL5 O compilador não faz distinção entre uma classe e um ponteiro para ela

 

MT5 construído em 1940

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
class A
{
public:
    int iValue;
};
//......................
A m_A[2];

void OnStart()
{
A a;

    m_A[0] =a; 
    m_A[1] = new A();
}
//+------------------------------------------------------------------+

Ela se compila nos dois casos:

A m_A[2]; // и так

A* m_A[2]; // и так

No primeiro caso, a saída é um objeto que não é apagado (criado novo) e um vazamento de memória

1 undeleted objects left
1 object of type A left
24 bytes of leaked memory

Ok, liberando manualmente ... e então o compilador (de repente) percebe que a matriz contém não-pontos:"ponteiro de objeto esperado".

delete m_A[1]; // Если 'm_A' массив объектов -> object pointer expected

Ok, eu o declaro como uma matriz de ponteiro.

A* m_A[2];

Ele compila! Isto era novidade para mim. Então, a MQL tem indicadores ou não? Porque com tipos embutidos, como char, int, etc., haverá

'*' - pointer cannot be used

Mas desta vez será em tempo de execução.

m_A[0] =a; // получаем: "invalid pointer access"

O que é lógico em princípio).

Há algumas perguntas sobre os resultados:

1. Para que servem esses indicadores na MQL, se eles não cumprem sua função principal, como os indicadores fazem no C/C++?

2. Por que devemos brincar com apagar, se a MT sabe exatamente quanta memória vazou e pode liberá-la automaticamente?

 

Ao apagar, você tem que verificar o tipo de ponteiro. Um objeto é criado com novo - deve ser apagado (segundo no exemplo) e o outro é automático (primeiro no exemplo), ele será apagado automaticamente.

 
Dmitry Fedoseev:

Ao apagar, você tem que verificar o tipo de ponteiro. Um objeto é criado com novo - deve ser excluído (segundo no exemplo), e o outro é automático (primeiro no exemplo), ele será automaticamente excluído.

Isto é, no primeiro casom_A[0] não conteráuma cópia doobjeto depilha'a' mas um ponteiro de algumtipoPOINTER_AUTOMÁTICO para aquele objeto local que se tornarátipoPOINTER_INVALIDO depois de sair da função (se ele fosse chamado de outra função)?

 
Então, em geral, o problema soa assim: o compilador permite que um ponteiro do tipoPOINTER_AUTOMÁTICO seja salvo em um ponteiro do tipoPOINTER_DYNAMIC, e vice versa.
 
SemenTalonov:

Isto é, no primeiro casom_A[0] não será uma cópia doobjeto depilha'a' mas um ponteiro de algumtipoPOINTER_AUTOMÁTICO para aquele objeto local que se tornarátipoPOINTER_INVALIDO depois de sair da função (se ele fosse chamado de outra função)?

Qualquer coisa pode se tornar um INVÁLIDO, se não for usado corretamente. A questão não é que oPOINTER_INVALIDO, mas que um objeto criado automaticamente também será apagado automaticamente.

Em nenhum caso, uma cópia de um objeto pode ser criada aqui. Um ponteiro é apenas um ponteiro - uma variável com um número indicando onde o objeto está, neste caso, o objeto "a". Portanto, você pode se referir ao objeto "a" com "a", ou pode fazê-lo com "m_A[0]", é um objeto, não dois objetos diferentes.

O princípio é simples: você mesmo criou o objeto, apague-o. Se você não a criou, deixe-a em paz. É tão fácil quanto isso.

 
SemenTalonov:
Em geral, o problema soa assim: o compilador permite salvar um ponteiro do tipoPOINTER_DYNAMIC em um ponteiro do tipoPOINTER_AUTOMÁTICOe vice versa.

Vice-versa. Um ponteiro do tipoPOINTER_DYNAMIC pode ser atribuído a um ponteiro do tipoPOINTER_AUTOMÁTICO. Mas isto é certo e bom - abre muitas possibilidades.

 

Eu não entendo o que está errado?

Pegamos um conjunto de objetos e equiparamos seu primeiro elemento ao objeto criado na pilha. Ao mesmo tempo, sem declarar o operador da cópia ! Isto já é um erro.

Bem, levando em conta que o objeto é muito simples, o construtor de cópias é gerado ali por padrão. E a matriz contém uma cópia do objeto criado.

Não há problema com as perguntas.

1. Os ponteiros cumprem seu papel, e eu pessoalmente só sinto falta de ponteiros para uma matriz.

A MQL não deve apagar o que não marcou. Dmitriy estava certo quando disse: "Crie um objeto, apague-o". Eu não gosto da prática do "coletor de lixo" em C# onde os objetos são apagados não quando eu quero, mas quando o montador quer.

 
Georgiy Merts:

Eu não entendo o que está errado?

Pegamos um conjunto de objetos e equiparamos seu primeiro elemento ao objeto criado na pilha. Ao mesmo tempo, sem declarar o operador da cópia ! Isto já é um erro.

Bem, levando em conta que o objeto é muito simples, o construtor de cópias é gerado ali por padrão. E a matriz contém uma cópia do objeto criado.

Era isso que eu esperava uma cópia de... O construtor de cópias padrão não é um erro.

MasDmitry afirma que um novo objeto será alocado na memória e um ponteiro do tipoPOINTER_AUTOMÁTICO será devolvidoe não haverá cópia.

Todos entendem as peculiaridades da MQL à sua maneira)

 
SemenTalonov:

Era o que eu esperava a cópia... O construtor de cópias padrão não é um erro.

MasDmitry diz que um novo objeto será alocado na memória e um ponteiro do tipoPOINTER_AUTOMÁTICO será devolvido.

Todos entendem as peculiaridades da MQL à sua maneira)

O que você quer dizer com "não é um erro"? Você está usando um operador que não está definido.

Bem, você tem lá um objeto praticamente vazio, mas e se houvesse outros subobjetos neste objeto, que exigiriam inicialização, e este objeto em si exigiria uma solicitação de recursos ?

Parece-me que você não pode usar algo que não está declarado.

"Quirks" que eu não vi, acho que Dimitri está errado sobre "nenhuma cópia do objeto" - e a razão, mais uma vez, é que uma declaração não declarada é usada.

 

De onde vem uma cópia de um objeto? Uma cópia de um ponteiro, sim, mas apontando para o mesmo objeto.

 
Georgiy Merts:

O que você quer dizer com "sem erros" ??? Você está usando um operador que não está definido.

Meu argumento é que um construtor de cópias explicitamente declarado não mudaria nada neste teste.

Como você não vê o óbvio...

Um ponteiro vai para um item de uma matriz de objetos e um objeto vai para um item de uma matriz de ponteiros... está realmente tudo bem?

no primeiro caso a matriz vai um ponteiro para um objeto no segundo caso o construtor de cópias deve funcionar, como estas operações podem ser equivalentes?