Freigeben über


Kopierkonstruktoren und Kopierzuweisungsoperatoren (C++)

Hinweis

Ab C ++11 werden zwei Arten von Aufgaben unterstützt: Kopierzuweisung und Bewegungszuweisung. In diesem Artikel bedeutet "Zuweisung" immer "Kopierzuweisung", sofern nicht explizit anders angegeben. Informationen zu Bewegungszuweisungen finden Sie unter Bewegungskonstruktoren und Bewegungszuweisungsoperatoren (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 nach 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 vorhergehende Code kann "Den Inhalt von FILE1.DAT auf FILE2.DAT kopieren" oder "FILE2.DAT ignorieren und b als zweiten Ziehpunkt für FILE1.DAT erstellen" bedeuten. Jeder Klasse muss wie folgt eine entsprechende Kopiersemantik beigefügt werden:

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

  • Verwenden Sie den Kopierkonstruktor.

Wenn Sie keinen Kopierkonstruktor deklarieren, generiert der Compiler einen memberweisen Kopierkonstruktor für Sie. Ähnlicherweise, wenn Sie keinen Kopierkonstruktoroperator deklarieren, generiert der Compiler einen memberweisen Kopierkonstruktoroperator für Sie. Das Deklarieren eines Kopierkonstruktors unterdrückt nicht den vom Compiler generierten Kopierzuweisungsoperator (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. Zum 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

Nutzen Sie soweit möglich für den Kopierkonstruktor den Argumenttyp const ClassName&. Dadurch wird verhindert, dass der Kopierkonstruktor versehentlich das kopierte Objekt ändert. Außerdem können Sie aus const Objekten kopieren.

Vom Compiler generierte Kopierkonstruktoren

Vom Compiler generierte Kopierkonstruktoren, wie benutzerdefinierte Kopierkonstruktoren, verfügen über ein einzelnes Argument vom Typ „Verweis auf class-name.“ Eine Ausnahme liegt vor, wenn alle Basisklassen und Memberklassen Kopierkonstruktoren so deklariert haben, dass sie ein einzelnes Argument vom Typ const class-name& akzeptieren. In einem solchen Fall ist das vom Compiler generierte Argument eines Kopierkonstruktors auch const.

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

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

Hinweis

Wenn virtuelle Basisklassen von Kopierkonstruktoren – entweder vom Compiler generiert oder benutzerdefiniert – initialisiert werden, werden sie nur einmal initialisiert: bei der Erstellung.

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

Weitere Informationen zu überladenen Zuweisungsoperatoren finden Sie unter Zuweisung.