MQL5 Il compilatore non distingue tra una classe e un puntatore ad essa - pagina 5

 
Il segno = copia l'area di memoria di un oggetto nell'area di memoria di un altro oggetto. Tutti gli oggetti rimangono dove erano.
 
Vladimir Simakov:
Non c'è modo di attivarlo. È una pura perdita di memoria.

Fallo in modo che possa essere evocato.

 

A proposito, signori sviluppatori, è meglio risolvere questo problema. Dopo tutto, new restituisce un puntatore, quindi aggiungi un controllo che all'altra estremità = anche un puntatore, rimuovi la conversione implicita (A) new A(); come ho capito - questo è ciò che accade.

 
Vladimir Simakov:

A proposito, cari sviluppatori, è meglio che sistemi questo. Dopo tutto new restituisce davvero un puntatore, quindi aggiungi un controllo che l'altra estremità = anche un puntatore, rimuovi la conversione implicita (A) new A(); come ho capito - questo è ciò che accade.

C'è una chiamata per questo operatore

Forum sul trading, sistemi di trading automatico e test di strategia

Il compilatore MQL5 non distingue tra una classe e un puntatore

fxsaber, 2019.01.10 06:36

Da quando sono definiti (domanda per gli sviluppatori)

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

E come funzionano? Il seguente codice compilato sembra delirante

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


Approssimativamente, si presenta così

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:

Ecco la chiamata a questo operatore


Approssimativamente, si presenta così

Sì, ho capito. Non è un brutto rastrello. A proposito, questo sovraccarico dell'operatore = non esiste in C++, giura VS.
 

Prima di fare un polverone, sarebbe bene sapere che in MQL per tutta la vita i puntatori sono stati implicitamente castati a oggetti (dereferenziati), è comodo e tutti si sono abituati. Invece del difficile da leggere a()->b()->c()->d() si può scrivere nel solito formato OOP: a().b().c().d(), e fare meno trasformazioni inutili durante il passaggio alle funzioni. E ora per l'insoddisfazione di qualcuno si cambia tutto?

 
Alexey Navoykov:

Prima di farne un dramma, sarebbe bello sapere che in MQL per tutta la vita i puntatori sono stati castati a oggetti implicitamente (dereferenziati), è comodo e tutti si sono abituati. Invece del difficile da leggere a()->b()->c()->d() si può scrivere nel solito formato OOP: a().b().c().d(), e fare meno trasformazioni inutili durante il passaggio alle funzioni. E ora per l'insoddisfazione di qualcuno si cambia tutto?

Non si tratta di casting. Non ci sei entrato.

 

Se siamo guidati dal prototipo dichiarato di MQL - C++.

In C++, l'operatore new restituisce un puntatore, rispettivamente, se m_A è un array di oggetti:

m_A[1] = new A();

ci sarebbe un errore di tipo qui.

Questa è la linea che il compilatore avrebbe saltato:

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

Ma causerebbe una perdita di memoria.


Sarebbe bello se MQL avesse lo stesso comportamento.

 
Alexey Navoykov:

Prima di iniziare a fare storie, dovreste sapere che in MQL per tutta la vita i puntatori sono stati implicitamente castati a oggetti (dereferenziati), è comodo e tutti si sono abituati a questo. Invece del difficile da leggere a()->b()->c()->d() si può scrivere nel solito formato OOP: a().b().c().d(), e fare meno trasformazioni inutili durante il passaggio alle funzioni. E ora per l'insoddisfazione di qualcuno si cambia tutto?

E se si entra nel dettaglio con alcuni semplici esempi.

A a;

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

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

Come risultato, abbiamo

1. a' ottiene una copia dell'oggetto creato, il puntatore al nuovo oggetto creato viene perso

2. Cosa succederà ad 'a' se new non riesce a creare/allocare la memoria di un oggetto?

Il secondo caso (al contrario)

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

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

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

1. Dopo l'uscita dalla funzione, l'oggetto 'b' deve essere distrutto come oggetto locale.

a cosa si riferirà allora "a"?

2. o l'operatore di copia funzionerà ancora e 'b' sarà copiato dal puntatore 'a'? e se 'a' non è stato definito prima?

 
SemenTalonov:

Il secondo caso (al contrario)

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

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

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


Qui è viceversa - un puntatore a è implicitamente castato in un oggetto (dereferenziato) e poi operator= è applicato ad esso. fxsaber lo ha anche menzionato ieri.

Anche se logicamente non contraddice le regole del MQL (poiché chiamare operator= è equivalente a chiamare qualsiasi altro metodo dell'oggetto), porta a una comprensione ambigua di tale codice e a errori difficili da trovare. E questo non riguarda solo operator= ma anche == e !=. Forse questo casting dovrebbe essere proibito anche per altri operatori, perché in C++ si può applicare agli operatori: +-<>[].

Il breve verdetto è questo: quando si applicano gli operatori che sono permessi per i puntatori in C++ ad un puntatore, non permettono un casting implicito di questo puntatore ad un oggetto. Corrispondentemente, l'esempio precedente causerebbe un errore di compilazione.