Kopieren von Konstruktoren und Kopieren von Zuordnungsoperatoren (C++)

Hinweis

Ab C++11 werden zwei Arten von Aufgaben in der Sprache unterstützt: Kopieren von Aufgaben und Verschieben von Aufgaben. In diesem Artikel bedeutet "Zuweisung" immer "Kopierzuweisung", sofern nicht explizit anders angegeben. Informationen zur Verschiebungszuweisung finden Sie unter Move Constructors and Move Assignment Operators (C++).For information about move assignment operators (C++).

Objekte können sowohl mit dem Zuordnungsvorgang als auch dem Initialisierungsvorgang kopiert werden.

  • Zuweisung: Wenn dem Wert eines Objekts ein anderes Objekt zugewiesen wird, wird das erste Objekt in das zweite Objekt kopiert. Dieser Code kopiert also den Wert von b :a

    Point a, b;
    ...
    a = b;
    
  • Initialisierung: Initialisierung tritt auf, wenn Sie ein neues Objekt deklarieren, Wenn Sie Funktionsargumente nach Wert übergeben oder wenn Sie einen Wert aus einer Funktion zurückgeben.

Sie können die Semantik von "kopieren" für Objekte des Klassentyps definieren. Betrachten Sie z. B. diesen Code:

TextFile a, b;
a.Open( "FILE1.DAT" );
b.Open( "FILE2.DAT" );
b = a;

Der vorangehende Code könnte "den Inhalt von FILE1 kopieren" bedeuten. DAT in DATEI2. DAT" oder es könnte "FILE2 ignorieren" bedeuten. DAT und einen zweiten Handle zu FILE1.DAT erstellen b ." Sie müssen die entsprechende Kopiersemantik wie folgt an jede Klasse anfügen:

  • Verwenden Sie einen Zuordnungsoperator operator= , der einen Verweis auf den Klassentyp zurückgibt, und verwendet einen Parameter, der per const Verweis übergeben wird , z ClassName& operator=(const ClassName& x);. B. . .

  • Verwenden Sie den Kopierkonstruktor.

Wenn Sie keinen Kopierkonstruktor deklarieren, generiert der Compiler einen memberweisen Kopierkonstruktor für Sie. Ebenso generiert der Compiler, wenn Sie keinen Kopierzuweisungsoperator deklarieren, einen memberweisen Kopierzuweisungsoperator für Sie. Durch das Deklarieren eines Kopierkonstruktors wird der vom Compiler generierte Kopierzuweisungsoperator nicht unterdrückt und umgekehrt. Wenn Sie eines der beiden Implementieren, empfehlen wir, auch das andere zu implementieren. Wenn Sie beide Implementieren, ist die Bedeutung des Codes klar.

Der Kopierkonstruktor verwendet ein Argument vom Typ ClassName&, wobei ClassName der Name der Klasse ist. Beispiel:

// spec1_copying_class_objects.cpp
class Window
{
public:
    Window( const Window& );            // Declare copy constructor.
    Window& operator=(const Window& x); // Declare copy assignment.
    // ...
};

int main()
{
}

Hinweis

Legen Sie den Typ des Arguments const ClassName& des Kopierkonstruktors nach Möglichkeit fest. Dadurch wird verhindert, dass der Kopierkonstruktor versehentlich das kopierte Objekt ändert. Außerdem können Sie aus const Objekten kopieren.

Vom Compiler generierte Kopierkonstruktoren

Compilergenerierte Kopierkonstruktoren, z. B. benutzerdefinierte Kopierkonstruktoren, weisen ein einzelnes Argument vom Typ "Verweis auf Klassenname" auf. Eine Ausnahme ist, wenn alle Basisklassen und Memberklassen Kopierkonstruktoren haben, die als ein einzelnes Argument vom Typ constKlassenname& deklariert wurden. In einem solchen Fall ist auch constdas Argument des compilergenerierten Kopierkonstruktors .

Wenn der Argumenttyp für den Kopierkonstruktor nicht constlautet, generiert die Initialisierung durch Kopieren eines const Objekts einen Fehler. Die Umkehrung ist nicht wahr: Wenn das Argument lautet const, können Sie initialisieren, indem Sie ein Objekt kopieren, das nicht constist.

Compilergenerierte Zuordnungsoperatoren folgen demselben Muster für const. Sie nehmen ein einzelnes Argument vom Typ ClassName& , es sei denn, die Zuordnungsoperatoren in allen Basis- und Memberklassen nehmen Argumente vom Typ const ClassName&. In diesem Fall verwendet der generierte Zuordnungsoperator für die Klasse ein const Argument.

Hinweis

Wenn virtuelle Basisklassen durch Kopierkonstruktoren initialisiert werden, unabhängig davon, ob compilergeneriert oder benutzerdefinierte, werden sie nur einmal initialisiert: an dem Punkt, an dem sie erstellt werden.

Die Auswirkungen ähneln dem Kopierkonstruktor. Wenn der Argumenttyp nicht constlautet, generiert die Zuordnung eines const Objekts einen Fehler. Die Umkehrung ist nicht wahr: Wenn ein const Wert einem Wert zugewiesen ist, der nicht constder Fall ist, wird die Zuordnung erfolgreich ausgeführt.

Weitere Informationen zu überladenen Zuordnungsoperatoren finden Sie unter "Zuordnung".