Fehler, Irrtümer, Fragen - Seite 1890

 
fxsaber:
Was ist der Ausführungsfehler?

Das stimmt, man kann nicht von unten nach oben fahren, sondern nur von oben nach unten. Dies geschieht aus Gründen der Sicherheit.

Man kann es nicht mit C++ vergleichen - dort kann alles auf alles reduziert werden.

 
Комбинатор:
In C++ funktioniert es auch nur, wenn ein Zeiger auf eine Basisklasse auf ihren Nachfahren zeigt.

Ich weiß nicht, was Sie damit meinen, aber dieser Code:

class CLASS1
{
public:
  int i;  
};

class CLASS2 : public CLASS1 {};

int main() {
  CLASS1 _object;
  CLASS2 *_ptr = (CLASS2*)&_object;  
  _ptr->i = 1;

   return 0;
}

funktioniert in C++, was ich oben geschrieben habe. Und hier ist der gleiche Code (unter Berücksichtigung der MQL-Syntax):

class CLASS1
{
public:
  int i;  
};

class CLASS2 : public CLASS1 {};

int OnInit() {
  CLASS1 _object;
  CLASS2 *_ptr = dynamic_cast<CLASS2 *>(&_object);
  
  _ptr.i = 1;

   return 0;
}
funktioniert nicht mehr, weil _ptr NULL wird
Das wirft die Frage auf, ob es sich um einen Fehler in MQL handelt und ob er behoben wird oder ob er so bleibt.
 
Renat Fatkhullin:

Das stimmt, man kann nicht von unten nach oben fahren, sondern nur von oben nach unten. Dies geschieht aus Gründen der Sicherheit.

Man kann es nicht mit C++ vergleichen - dort kann alles auf alles reduziert werden.


Jetzt habe ich es verstanden, danke für die Klarstellung ))
 
Konstantin:

Ich weiß nicht, was Sie damit meinen, aber dieser Code:

Versuchen Sie, es zu verstehen. Beginnen Sie damit, dass dynamic_cast in den Pluszeichen funktioniert. Wenn Sie es selbst herausfinden, sind Sie viel besser dran.
 
Renat Fatkhullin:

Das stimmt, man kann nicht von unten nach oben fahren, sondern nur von oben nach unten.

Was meinen Sie, Sie können nicht von einer Basisklasse auf einen Nachkommen übertragen werden?
 
Комбинатор:
Sie meinen, Sie können nicht von einer Basisklasse auf einen Nachkommen übertragen?

Ja, für den Fall, dass die Basisklasse keinen tatsächlich konstruierten Abkömmling hat.

 
Renat Fatkhullin:

Das stimmt, man kann nicht von unten nach oben fahren, sondern nur von oben nach unten. Dies geschieht aus Gründen der Sicherheit.

Wenn wir den Zeiger von oben nach unten, d. h. zum übergeordneten Element, bringen und dann den Zeiger an eine andere Stelle im Anwendungsbereich übergeben, sind die Felder des nachgeordneten Elements dort verfügbar?
 
Renat Fatkhullin:

Ja.

Renate, weißt du, was dynamic_cast ist?
 
Комбинатор:
Renat, wissen Sie, was dynamic_cast ist?

Ja, natürlich.

Sehen Sie sich den besprochenen Teil des MQL5-Codes an. Es wird eine Basisinstanz erstellt und dann heroisch versucht, über Dynamiccast in einen Nachfahren zu konvertieren, was die Sicherheit verletzt. Nun, das ist natürlich schade.

 

Das gleiche Beispiel wird in der Dokumentation direkt besprochen und erläutert. Der dynamische Cast zur Laufzeit wird erst ausgelöst, nachdem das Sicherheitssystem und die Zulässigkeit von Konvertierungen geprüft wurden. Jedes MQL5-Objekt verfügt über alle Meta-Informationen zur Überprüfung der Rechte zur Laufzeit. Dies ist kein leeres C++.


Dynamische Typkonvertierung mit dem dynamic_cast-Operator

Mit dem dynamic_cast-Operator, der nur auf Klassenzeiger angewendet werden kann, ist es möglich, Typen dynamisch zu casten. In diesem Fall wird die Überprüfung der Korrektheit der Typen zum Zeitpunkt der Programmausführung durchgeführt. Das bedeutet, dass der Compiler bei Verwendung des dynamic_cast-Operators den für die Konvertierung verwendeten Datentyp nicht überprüft. Wenn ein Zeiger in einen Datentyp umgewandelt wird, der nicht der eigentliche Objekttyp ist, ist das Ergebnis NULL.

dynamic_cast<type-id> ( Ausdruck )

Der Parameter type-id in spitzen Klammern muss ein Zeiger auf einen zuvor definierten Klassentyp sein . DerTyp des Ausdrucksoperanden kann (im Gegensatz zu C++) alles außer void sein.

Beispiel:

Klasse CBar { };
class CFoo :public CBar { };

voidOnStart( )
{
CBar-Bar;
//--- dynamische Umwandlung des Zeigertyps *bar in den Zeiger *foo ist zulässig
CFoo *foo =dynamic_cast<CFoo*>(&bar);//--- kein kritischer Fehler bei der Ausführung
Print(foo);// foo=NULL
//--- der explizite Versuch, eine Referenz des Bar-Objekts in ein Foo-Objekt zu übertragen, ist verboten
foo=(CFoo *)&bar;// ein kritischer Ausführungsfehler wird auftreten
Print(foo);// diese Zeile wird nicht ausgeführt
}