Warum CObjects Kopierkonstruktor und -zuweisung deaktivieren

8

Der Kopierkonstruktor und die Zuweisung des Root-Objekts CObject des MFC sind standardmäßig deaktiviert.

  

Die standardmäßige C ++ - Standardklassenkopie   Konstruktor macht ein Mitglied-für-Mitglied   Kopieren. Die Anwesenheit des Privaten   CObject Kopierkonstruktor garantiert a   Compiler-Fehlermeldung, wenn die Kopie   Konstruktor Ihrer Klasse wird benötigt   aber nicht verfügbar. Sie müssen deshalb   Stellen Sie einen Kopierkonstruktor zur Verfügung, wenn Sie   Klasse benötigt diese Fähigkeit.

  • In CObjects Quellcode gibt es einen Kommentar:
  

Deaktivieren Sie den Kopierkonstruktor und   Zuweisung standardmäßig, so dass Sie Compiler-Fehler anstelle von unerwartetem Verhalten erhalten, wenn Sie Objekte nach Wert übergeben oder Objekte zuweisen.

Meine Frage ist, was ist das Problem mit dem standardmäßigen Bit-für-Bit-Kopierkonstruktor für diese CObject-Klasse? Meiner Meinung nach wäre es besser, uns den Standard-Kopierkonstruktor zu geben, und wir könnten bei Bedarf einen solchen erstellen (deep copy)

    
Baiyan Huang 21.06.2010, 13:57
quelle

2 Antworten

6

Der standardmäßige Kopierkonstruktor ist Member-by-Member, nicht bitweise.

Die meisten CObject-abgeleiteten Klassen enthalten - und verwalten direkt - einige Systemressourcen, die keine Referenzzählung oder ähnlichen Mechanismus haben, so dass die Wahl wahrscheinlich mit dem Standard-Anwendungsfall getroffen wurde.

z.B. CGDIObject ist grob:

%Vor%

Der standardmäßige Kopierkonstruktor wäre hier gefährlich (was zu doppelter Zerstörung führt), vorausgesetzt, ein "korrekter" Kopierkonstruktor ist überraschend hart und teuer.

Ein weiterer Grund kann sein, dass die meisten CObject-abgeleiteten Klassen mutiert und somit als Referenz übergeben werden sollen. Ein Konstruktor für fehlende Kopien fängt unbeabsichtigte Kopien ab, die eine Kopie mutieren, und nicht das übergebene Objekt:

%Vor%

Das "& amp;" weglassen gibt Ihnen einen Code, der gut kompiliert, aber eine temporäre Kopie erstellt, diese ändert und dann ablegt, während mo unverändert bleibt.

Sehr viele APIs folgen diesem Muster, da MFC nicht auf Ausnahmen zur Fehlerbehandlung angewiesen ist (aus historischen Gründen: Nicht alle zielgerichteten Compiler unterstützten sie gut, und MFC erfordert eine Menge zusätzlicher Ressourcenbehandlung, die mit Ausnahmen schmerzhaft wird) .

Ich denke nicht, dass diese Entscheidungen gut sind, z.B. abgeleitete Klassen sollten den standardmäßigen Kopierkonstruktor verwenden dürfen, wenn ihre Mitglieder es zulassen (und die meisten Mitglieder sollten dies zulassen).

Die Entscheidung entspricht jedoch der "Denkweise" von MFC und den Anforderungen / Einschränkungen der Zeit, in der MFC erstellt wurde.

    
peterchen 21.06.2010, 14:39
quelle
3

Betrachten Sie Folgendes:

%Vor%

Wenn Sie nun CMyHandle kopieren, wird das Handle zweimal geschlossen, und nachdem eine der CMyHandle Instanzen zerstört wurde, wird die andere Instanz ungültig.

Da eine große Anzahl von MFC-Klassen Handles verwaltet, ist es sinnvoll, den Ersteller der Klasse zum expliziten Überschreiben zu zwingen, um Kopierkonstruktoren zu erstellen und Zuweisungsoperatoren zu kopieren.

EDIT: Zum Beispiel:

%Vor%     
Billy ONeal 21.06.2010 14:30
quelle

Tags und Links