MQL5 Der Compiler unterscheidet nicht zwischen einer Klasse und einem Zeiger auf sie - Seite 5

 
Das Zeichen = kopiert den Speicherbereich eines Objekts in den Speicherbereich eines anderen Objekts. Alle Objekte bleiben, wo sie waren.
 
Vladimir Simakov:
Es gibt keine Möglichkeit, sie auszulösen. Das ist reines Speicherleck.

Machen Sie es so, dass es herbeigerufen werden kann.

 

Übrigens, meine Herren Entwickler, wir sollten das besser in Ordnung bringen. Immerhin gibt new einen Zeiger zurück, also fügen Sie eine Prüfung hinzu, dass am anderen Ende = auch ein Zeiger, entfernen Sie die implizite Umwandlung (A) new A(); wie ich es verstehe - das ist, was passiert.

 
Vladimir Simakov:

Übrigens, liebe Entwickler, wir sollten das besser in Ordnung bringen. Schließlich gibt new wirklich einen Zeiger zurück, also fügen Sie eine Prüfung hinzu, dass das andere Ende = auch ein Zeiger ist, entfernen Sie die implizite Umwandlung (A) new A(); wie ich es verstanden habe - das ist, was passiert.

Es gibt einen Aufruf für diesen Betreiber

Forum zum Thema Handel, automatisierte Handelssysteme und Strategietests

Der MQL5 Compiler unterscheidet nicht zwischen einer Klasse und einem Zeiger

fxsaber, 2019.01.10 06:36

Seit wann sind diese definiert (Frage an die Entwickler)

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

Und wie funktionieren sie? Der folgende kompilierte Code sieht wahnhaft aus

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


Grob gesagt, sieht das folgendermaßen aus

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:

Das war's mit dem Anruf bei diesem Betreiber


Grob gesagt, sieht das folgendermaßen aus

Ja, ich habe verstanden. Es ist keine schlechte Harke. Übrigens, diese Operatorüberladung = gibt es in C++ nicht, schwört VS.
 

Bevor Sie sich darüber aufregen, sollten Sie wissen, dass in MQL Zeiger schon immer implizit in Objekte umgewandelt (dereferenziert) wurden, das ist bequem und jeder hat sich daran gewöhnt. Anstelle des schwer lesbaren a()->b()->c()->d() können Sie im üblichen OOP-Format schreiben: a().b().c().d(), und weniger unnötige Umwandlungen bei der Übergabe an Funktionen vornehmen. Und jetzt ändern Sie alles, weil jemand unzufrieden ist?

 
Alexey Navoykov:

Bevor Sie einen Aufstand darüber machen, wäre es schön zu wissen, dass in MQL alle ihr Leben Zeiger auf Objekte implizit (dereferenced) gecastet wurden, es ist bequem und jeder hat sich daran gewöhnt. Anstelle des schwer lesbaren a()->b()->c()->d() können Sie im üblichen OOP-Format schreiben: a().b().c().d(), und weniger unnötige Umwandlungen bei der Übergabe an Funktionen. Und jetzt ändern Sie alles, weil jemand unzufrieden ist?

Es geht nicht ums Casting. Du bist nicht dazu gekommen.

 

Wenn wir uns an dem deklarierten Prototyp von MQL - C++ orientieren.

In C++ gibt der new-Operator einen Zeiger zurück, bzw. wenn m_A ein Array von Objekten ist:

m_A[1] = new A();

würde es hier einen Typfehler geben.

Dies ist die Zeile, die der Compiler übersprungen hätte:

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

Aber das würde ein Speicherleck verursachen.


Es wäre schön, wenn MQL das gleiche Verhalten hätte.

 
Alexey Navoykov:

Bevor Sie anfangen, sich darüber aufzuregen, sollten Sie wissen, dass in MQL Zeiger ihr ganzes Leben lang implizit in Objekte umgewandelt (dereferenziert) wurden, es ist bequem und jeder hat sich daran gewöhnt. Anstelle des schwer lesbaren a()->b()->c()->d() können Sie im üblichen OOP-Format schreiben: a().b().c().d(), und weniger unnötige Umwandlungen bei der Übergabe an Funktionen. Und jetzt ändern Sie alles, weil jemand unzufrieden ist?

Und wenn Sie mit einigen einfachen Beispielen ins Detail gehen.

A a;

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

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

Als Ergebnis haben wir

1. a' eine Kopie des erstellten Objekts erhält, geht der Zeiger auf das neu erstellte Objekt verloren

2) Was passiert mit "a", wenn new kein Objekt erstellen bzw. keinen Speicherplatz zuweisen kann?

Der zweite Fall (im Gegenteil)

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

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

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

Nach Beendigung der Funktion muss das Objekt 'b' als lokales Objekt zerstört werden.

worauf bezieht sich dann 'a'?

2. oder funktioniert der Kopieroperator trotzdem und 'b' wird durch den 'a'-Zeiger kopiert ? und wenn 'a' vorher nicht definiert wurde ?

 
SemenTalonov:

Der zweite Fall (im Gegenteil)

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

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

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


Hier ist es umgekehrt - ein Zeiger a wird implizit in ein Objekt gecastet (dereferenziert) und dann wird operator= darauf angewandt. fxsaber hat es gestern auch erwähnt.

Obwohl dies logisch gesehen nicht im Widerspruch zu den MQL-Regeln steht (da der Aufruf von operator= gleichbedeutend mit dem Aufruf jeder anderen Objektmethode ist), führt es zu einem unklaren Verständnis von solchem Code und schwer zu findenden Fehlern. Und das betrifft nicht nur operator=, sondern auch == und !=. Vielleicht sollte ein solches Casting auch für andere Operatoren verboten werden, denn in C++ kann man auf Operatoren anwenden: +-<>[].

Kurz gesagt: Wenn man Operatoren, die in C++ für Zeiger erlaubt sind, auf einen Zeiger anwendet, sollte man ein implizites Casting dieses Zeigers in ein Objekt verbieten. Dementsprechend würde das obige Beispiel einen Kompilierungsfehler verursachen.

Grund der Beschwerde: