Fehler, Irrtümer, Fragen - Seite 2357

 
Ilya Malev:

Danke für die ausführliche Antwort, allerdings verstehe ich die Logik nicht ganz.

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

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, A::f() direkt aufzurufen, einen Kompilierungsfehler "not a static method call" erzeugt)

1) Ich habe geschrieben, dass dies ein offensichtlicher Fehler ist, den wir auf jeden Fall beheben werden.

2) der Kopierkonstruktor wird vom Compiler generiert, wenn er nicht vom Benutzer deklariert wird

3) Die Frage ist nicht ganz klar.
Aus dem Kontext der Diskussion:
Man könnte lange darüber streiten, ob ein Zeiger "dereferenziert" werden soll, wenn kein Zugriff auf ihn besteht.
Die Dereferenzierungsoperation (Abrufen des tatsächlichen Zeigers vom Handle) ist "interner" (nicht benutzerdefinierter) und teurer Code (im Vergleich zu einem nicht vorhandenen Code).
Warum eine Dereferenzierung durchführen, wenn es keinen Zeigerzugriff gibt?
Solange dies der Fall ist, wird die Dereferenzierung vom Optimierer entfernt, wenn kein Zeigerzugriff erfolgt.

 
Ilya Malev:

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

Sie verwechseln das Thema.

Der Aufruf Devirtualisierung ist eine separate Optimierungsmethode, die nichts mit dem Vorhandensein oder Fehlen von Feldern in einem Objekt zu tun hat.

 
Ilyas:

2) der Kopierkonstruktor wird vom Compiler generiert, es sei denn, er wird vom Benutzer deklariert

Es gibt ein B-Objekt auf der linken Seite, warum wird der A::A(A&)-Konstruktor für dieses Objekt aufgerufen (oder erzeugt)? Dies widerspricht den Grundsätzen der OOP
 
Alexey Navoykov:
Es gibt ein Objekt B auf der linken Seite, warum wird der Konstruktor A::A() für dieses Objekt aufgerufen?

Denn in µl verhalten sich die Operatoren =, ==, !=, !&, &| und || immer so, wenn sich links ein Zeiger und rechts ein "Objekt" befindet. Und gleichzeitig können diese Operatoren nicht auf Zeigern überladen werden.

Also bitte, wenn Sie diesen Fehler beheben, machen Sie die oben genannten Operatoren überladbar für dynamische Objekte.

 
Metatrader 4 funktioniert nicht mehr, er funktioniert für eine Sekunde oder so, wenn ich starte, dann erscheint ein Ein-Klick-Handelsfenster in der oberen linken Ecke (Kaufen/Verkaufen) und dann schließt sich die App.
Gibt es Vorschläge, wie man das Problem beheben kann?
Vielen Dank im Voraus für Ihre Hilfe.
 
Ilya Malev:

Denn so verhalten sich die Operatoren =, ==, !=, !&, && und || in µl immer, wenn sich der Zeiger links und der Typ "Objekt" rechts befindet.

Was hat der Zeiger damit zu tun? Ich habe es Ihnen bereits hier gesagt. Hier funktioniert es genauso ohne Zeiger.
 
Alexey Navoykov:
Es gibt ein Objekt B auf der linken Seite, warum wird der A::A(A&)-Konstruktor für dieses Objekt aufgerufen (oder erzeugt)? Dies widerspricht den Prinzipien der OOP

Ich stimme Ihnen voll und ganz zu und habe bereits geschrieben, dass dies ein Fehler ist, der korrigiert werden wird.

In diesem Fall hat der Compiler eine geeignete Überladung bei der Vererbung ausgewählt, was bei der Konstruktion des Objekts nicht hätte geschehen dürfen.

 
Ilyas:

Man kann lange darüber streiten, ob ein Zeiger "dereferenziert" werden soll, wenn kein Zugriff auf ihn besteht.

Die Dereferenzierungsoperation (einen echten Zeiger von einem Handle zu erhalten) ist "interner" (nicht benutzerdefinierter) und teurer (im Vergleich zum Nichtvorhandensein) Code.
Warum eine Dereferenzierung durchführen, wenn es keinen Zeigerzugriff gibt?

Denn eine Liste virtueller Methoden ist Teil der Informationen eines Objekts, nicht weniger wichtig als die Daten selbst, und der Zugriff auf virtuelle Methoden ist ein Zeigerzugriff. Wenn ich zum Beispiel in meinem Beispiel schreibe

  A* aa=a;
  B* b1=a;   
  b1=aa;
  b1.f();

erhalte ich wieder B::f(), obwohl sich dieser Code ausdrücklich auf die Zuweisung des A*-Objekts bezieht, das von A "kopiert" und von A* referenziert wurde. Dies ist ein tieferes Problem als der Aufruf des "falschen" Kopierkonstruktors. Aber selbst wenn das Objekt keine virtuellen Methoden gehabt hätte, hätten wir die Gültigkeit des Zeigers beim Zugriff darauf überprüfen müssen.

 
Alexey Navoykov:
Es gibt ein B-Objekt auf der linken Seite, warum wird der A::A(A&)-Konstruktor für dieses Objekt aufgerufen (oder erzeugt)? Dies widerspricht den Prinzipien der OOP

Sind Sie sicher, dass es dort überhaupt etwas gibt, das so heißt? Ich habe es in x32 überprüft:

class A {
public:
        A()           { Print(__FUNCSIG__); }
        A( const A& ) { Print(__FUNCSIG__); }
} a;
class B : public A {
public:
        B()           { Print(__FUNCSIG__); }
        B( const B& ) { Print(__FUNCSIG__); }
} *b = a;
void OnStart() {}

Ergebnis: A::A()
und sonst nichts!

 
A100:

Sind Sie sicher, dass es dort überhaupt etwas gibt, das so heißt? Ich habe es in x32 überprüft:

Ergebnis: A::A()
und sonst nichts!

Also, ab zum Generator/Optimierer-Dump, um die I's zu überprüfen