Fehler, Irrtümer, Fragen - Seite 2356

 
A100:

in C++: A::f()

Was besagt dieser Code?

((A*)&b).f();
 
fxsaber:

Was besagt dieser Code?

Es ist das Gleiche.

 
Ilya Malev:

Das ist dasselbe.

als MQL (vorausgesetzt, es wird in C++-Form konvertiert). Aber Sie hätten es selbst überprüfen können
 
A100:
Das und MQL (vorausgesetzt, es wird in die C++-Form konvertiert). Aber Sie hätten es selbst überprüfen können

Geprüft:


 
Ilya Malev:

Geprüft:

Ich glaube, Sie prüfen etwas falsch.

B*b1=a;

Ein solcher Eintrag in MQL bedeutet das Kopieren eines Objekts a - auf ein Objekt, das durch den Zeiger b1 lokalisiert wird. Im Allgemeinen sollte er natürlich nicht kompiliert werden.

Und um Objekte und Zeiger nicht zu verwechseln, sollten Sie für Zeiger das Präfix p verwenden

 
Ilya Malev:

Geprüft:

Bitte lassen Sie sich nicht auf dieses fehlgeleitete Verhalten einlassen.

Hier gibt es 2 Probleme(?):

  1. B *b1=a - ein expliziter Fehler, der Compiler sieht dieses Konstrukt als einen Aufruf des Kopieroperators A::A(const A &).

  2. Im ersten Fall hat der Optimierer festgestellt, dass A::A(const A &) leer ist, keine Mitglieder - kein Zugriff per "Zeiger" (tatsächlich gibt es keinen Code für den Aufruf des Kopieroperators, alles wurde herausgeschnitten)
    die virtuelle B::f() ist nicht überladen, so dass es sich statt eines virtuellen Aufrufs um einen einfachen Aufruf handelte; in B::f() gibt es keine Mitgliederadressierung, so dass der Zugriff über einen "Zeiger" ebenfalls gestrichen wurde

    Im zweiten Fall ist A::f() ein versuchter virtueller Aufruf, es gibt einen Zugriff per "Pointer", aber kein a1-Objekt, weil ein leerer Kopierkonstruktor A::A(const A &) auch für A *a1=b aufgerufen wurde
 
Ilyas:

Bitte verlassen Sie sich nicht auf dieses fehlgeleitete Verhalten.

Hier gibt es 2 Probleme(?):

Ich hoffe, dass Sie dieses fehlerhafte Verhalten beheben werden? (make a compilation error) Weil es möglich ist, einen solchen Fehler aus Versehen zu machen und der Compiler in keiner Weise reagiert.

 
Alexey Navoykov:

Ich hoffe, dass Sie dieses fehlerhafte Verhalten beheben werden? Denn es ist möglich, einen solchen Fehler aus Versehen zu machen, und der Compiler reagiert in keiner Weise darauf.

Ja, wir werden es in Ordnung bringen.

Die Priorität ist niedrig angesetzt, da nur leere Klassen funktionierenden Code erhalten

 
Ilyas:

Bitte verlassen Sie sich nicht auf dieses fehlgeleitete Verhalten.

Hier gibt es 2 Probleme(?):

  1. B *b1=a - ein offensichtlicher Fehler, da der Compiler dieses Konstrukt als einen Aufruf des Kopieroperators A::A(const A &) betrachtet

  2. Im ersten Fall hat der Optimierer festgestellt, dass A::A(const A &) leer ist, keine Mitglieder - kein Zugriff per "Zeiger" (tatsächlich gibt es keinen Code für den Aufruf des Kopieroperators, alles wurde herausgeschnitten)
    die virtuelle B::f() ist nicht überladen, so dass es sich statt eines virtuellen Aufrufs um einen einfachen Aufruf handelte; in B::f() gibt es keine Mitgliederadressierung, so dass der Zugriff über einen "Zeiger" ebenfalls gestrichen wurde

    Im zweiten Fall ist A::f() ein versuchter virtueller Aufruf, es gibt einen Zugriff per "Pointer", aber kein a1-Objekt, weil ein leerer Kopierkonstruktor A::A(const A &) auch für A *a1=b aufgerufen wurde

Danke für die ausführliche Antwort, aber ich bin etwas verwirrt über die Logik.

1) Warum sieht der Compiler das Konstrukt B* b1=a als Aufruf des Kopieroperators A::A(const A&), (statt als Aufruf von B::B(const A&), weil es die Klasse B links von operator= ist)

2) Warum hat der Compiler nicht die Warnung "copy constructor missing" ausgegeben?

3) warum ein "einfacher" Methodenaufruf für nicht existierende Objekte erlaubt ist (während der Versuch, B::f() direkt aufzurufen, einen Kompilierungsfehler "kein statischer Methodenaufruf" ergibt)

4) Und warum erlaubt der Compiler überhaupt einen "einfachen" virtuellen Methodenaufruf? Meiner Meinung nach sollte die Virtualität nicht vom Vorhandensein oder Fehlen von Daten im Objekt abhängen.

 
Ilya Malev:

1) Warum sieht der Compiler B* b1=a als einen Aufruf des Kopieroperators A::A(const A&), (anstatt B::B(const A&) aufzurufen, da es sich um die Klasse B links von operator= handelt)

Das ist genau richtig. Das ist ein weiterer MQL-Bug, dass der Compiler solche Dinge frei zulässt: B b = a; Das ist eine Verletzung der Kapselungsprinzipien. In C++ kompilieren solche Dinge natürlich nicht, eine explizite Konvertierung ist erforderlich. Und in alten MQL-Builds konnten solche Dinge auch nicht gemacht werden.