Utiliser le constructeur de copie en C++

Jinku Hu 12 octobre 2023
  1. Utilisez le constructeur de copie pour initialiser un objet à partir d’un autre objet du même type en C++
  2. Utilisez l’opérateur d’affectation de copie pour définir la surcharge de l’opérateur d’affectation pour l’objet en C++
Utiliser le constructeur de copie en C++

Cet article explique plusieurs méthodes d’utilisation d’un constructeur de copie en C++.

Utilisez le constructeur de copie pour initialiser un objet à partir d’un autre objet du même type en C++

Il existe plusieurs opérations dans la classe appelées collectivement contrôle de copie. Ces opérations définissent comment les objets du type de classe donné sont copiés, déplacés, affectés ou détruits. Dans cet article, nous nous concentrerons uniquement sur le constructeur de copie et l’affectation de copie.

Le constructeur de copie initialise l’objet en dupliquant la valeur de l’argument passé en référence (il est communément passé en référence const). La classe n’est pas obligée de définir le constructeur de copie comme toute autre opération de contrôle de copie car le compilateur définit automatiquement les opérations synthétisées pour les opérations non définies. Pourtant, souvent ces derniers peuvent causer des problèmes. Le constructeur de copie synthétisé copie chaque membre de l’objet argument dans l’objet en cours de création. Il peut y avoir des membres de certains autres types de classe, qui sont copiés par leur constructeur de copie. En revanche, les objets de type intégré sont copiés directement.

L’exemple de code suivant montre le comportement du constructeur de copie de MyClass, qui prend le seul argument obligatoire pour le constructeur de copie, puis initialise les données membres. D’un autre côté, le constructeur de copie peut avoir des arguments supplémentaires, qui doivent être facultatifs et avoir des valeurs par défaut.

Lorsque l’objet de type MyClass est créé en premier, le constructeur par défaut est invoqué ; cependant, si nous affectons m1 à la variable m3 nouvellement créée, le constructeur de copie est appelé. Cette dernière opération est également appelée initialisation de copie, qui peut utiliser un constructeur de copie ou déplacer un constructeur (discuté dans un autre article).

#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;
}

Production:

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

Utilisez l’opérateur d’affectation de copie pour définir la surcharge de l’opérateur d’affectation pour l’objet en C++

L’opérateur d’affectation de copie définit comment affecter des objets du même type. Le compilateur synthétise également cette opération si l’utilisateur ne la définit pas explicitement. L’affectation de copie est décrite de la même manière que d’autres fonctions de surcharge d’opérateur. Il prend un argument du même type que la classe et renvoie généralement la référence à l’opérande de gauche. Un opérateur d’affectation de copie doit être défini en tant que fonction membre.

L’extrait de code suivant ajoute l’opérateur d’affectation de copie pour le MyClass et l’invoque tout en affectant l’objet m2 au m1.

#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;
}

Production:

Constructor 1 is called-- -- -- -- -- -- -- -- --Constructor 1 is
    called-- -- -- -- -- -- -- -- --Copy Constructor is
        called-- -- -- -- -- -- -- -- --Copy Assignment is
            called-- -- -- -- -- -- -- -- --1221 1133 1221
Auteur: 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

Article connexe - C++ Constructor