Verwenden des Copy-Konstruktors in C++

Jinku Hu 12 Oktober 2023
  1. Verwenden des Copy-Konstruktors zum Initialisieren eines Objekts aus einem anderen Objekt desselben Typs in C++
  2. Mit dem Kopier-Zuweisungsoperator die Überladung des Zuweisungsoperators für das Objekt in C++ definieren
Verwenden des Copy-Konstruktors in C++

In diesem Artikel werden verschiedene Methoden zum Verwenden eines Kopierkonstruktors in C++ erläutert.

Verwenden des Copy-Konstruktors zum Initialisieren eines Objekts aus einem anderen Objekt desselben Typs in C++

Es gibt mehrere Operationen in der Klasse, die zusammenfassend Kopierkontrolle genannt werden. Diese Operationen definieren, wie die Objekte des gegebenen Klassentyps kopiert, verschoben, zugewiesen oder zerstört werden. In diesem Artikel konzentrieren wir uns nur auf den Kopierkonstruktor und die Kopierzuweisung.

Der Kopierkonstruktor initialisiert das Objekt, indem er den Wert des als Referenz übergebenen Arguments dupliziert (er wird üblicherweise als const-Referenz übergeben). Die Klasse muss den Kopierkonstruktor nicht wie andere Kopiersteueroperationen definieren, da der Compiler automatisch synthetisierte Operationen für undefinierte Operationen definiert. Dennoch können letztere oft Probleme verursachen. Der synthetisierte Kopierkonstruktor kopiert jeden Member des Argumentobjekts in das Objekt, das erstellt wird. Möglicherweise gibt es Member einiger anderer Klassentypen, die von ihrem Kopierkonstruktor kopiert werden. Im Gegensatz dazu werden eingebaute Typobjekte direkt kopiert.

Der folgende Beispielcode demonstriert das Verhalten des Kopierkonstruktors der MyClass, der das einzige obligatorische Argument für den Kopierkonstruktor übernimmt und dann Datenmember initialisiert. Andererseits kann der Kopierkonstruktor zusätzliche Argumente haben, die optional sein müssen und Standardwerte haben.

Beim Anlegen des Objekts vom Typ MyClass wird zunächst der Standardkonstruktor aufgerufen; Wenn wir jedoch der neu erstellten Variable m3 m1 zuweisen, wird der Kopierkonstruktor aufgerufen. Die letztere Operation wird auch Kopierinitialisierung genannt, die einen Kopierkonstruktor verwenden oder einen Konstruktor verschieben kann (in einem anderen Artikel besprochen).

#include <iostream>

using std::cout;
using std::endl;
using std::pair;

class MyClass {
 private:
  int n1{};
  int n2{};

 public:
  MyClass(int x, int y) : n1(x), n2(y) {
    cout << "Constructor 1 is called" << endl;
  };

  MyClass(const MyClass& src) {
    cout << "Copy Constructor is called " << endl;
    n1 = src.n1;
    n2 = src.n2;
  }

  auto getPair() { return pair<int, int>(n1, n2); }

  ~MyClass() = default;
};

int main() {
  MyClass m1(12, 21);
  cout << "------------------" << endl;
  MyClass m2(11, 33);
  cout << "------------------" << endl;
  MyClass m3 = m1;
  cout << "------------------" << endl;

  cout << m1.getPair().first << m1.getPair().second << endl;
  cout << m2.getPair().first << m2.getPair().second << endl;
  cout << m3.getPair().first << m3.getPair().second << endl;

  return EXIT_SUCCESS;
}

Ausgabe:

Constructor 1 is called
------------------
Constructor 1 is called
------------------
Copy Constructor is called
------------------
1221
1133
1221

Mit dem Kopier-Zuweisungsoperator die Überladung des Zuweisungsoperators für das Objekt in C++ definieren

Der Kopierzuweisungsoperator definiert, wie Objekte des gleichen Typs zugewiesen werden. Der Compiler synthetisiert diese Operation auch, wenn der Benutzer sie nicht explizit definiert. Die Kopierzuweisung wird ähnlich wie andere Funktionen zum Überladen von Operatoren beschrieben. Sie nimmt ein Argument vom gleichen Typ wie die Klasse und gibt normalerweise die Referenz auf den linken Operanden zurück. Ein Kopierzuweisungsoperator muss als Memberfunktion definiert werden.

Der nächste Codeausschnitt fügt den Kopierzuweisungsoperator für die MyClass hinzu und ruft ihn auf, während sie das m2-Objekt dem m1 zuweist.

#include <iostream>

using std::cout;
using std::endl;
using std::pair;

class MyClass {
 private:
  int n1{};
  int n2{};

 public:
  MyClass(int x, int y) : n1(x), n2(y) {
    cout << "Constructor 1 is called" << endl;
  };

  MyClass(const MyClass& src) {
    cout << "Copy Constructor is called " << endl;
    n1 = src.n1;
    n2 = src.n2;
  }

  MyClass& operator=(const MyClass& src) {
    cout << "Copy Assignment is called " << endl;
    n1 = src.n1;
    n2 = src.n2;
    return *this;
  }

  auto getPair() { return pair<int, int>(n1, n2); }

  ~MyClass() = default;
};

int main() {
  MyClass m1(12, 21);
  cout << "------------------" << endl;
  MyClass m2(11, 33);
  cout << "------------------" << endl;
  MyClass m3 = m1;
  cout << "------------------" << endl;
  m1 = m2;
  cout << "------------------" << endl;

  cout << m1.getPair().first << m1.getPair().second << endl;
  cout << m2.getPair().first << m2.getPair().second << endl;
  cout << m3.getPair().first << m3.getPair().second << endl;

  return EXIT_SUCCESS;
}

Ausgabe:

Constructor 1 is called
------------------
Constructor 1 is called
------------------
Copy Constructor is called
------------------
Copy Assignment is called
------------------
1221
1133
1221
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Verwandter Artikel - C++ Constructor