Implémenter des constructeurs de classe en C++

Jinku Hu 12 octobre 2023
  1. Que sont les constructeurs et comment ils fonctionnent en C++
  2. Implémenter plusieurs constructeurs de classes à l’aide de la surcharge en C++
Implémenter des constructeurs de classe en C++

Cet article présentera comment implémenter des constructeurs de classe en C++.

Que sont les constructeurs et comment ils fonctionnent en C++

Les constructeurs sont des fonctions membres spéciales qui définissent comment l’objet de classe doit être initialisé. Les constructeurs initialisent généralement les membres de données de la classe, et ils sont exécutés lorsqu’un objet de classe est créé. Certaines fonctionnalités spécifiques des fonctions constructeur sont qu’elles portent le même nom que la classe elle-même et ne peuvent pas avoir de type de retour. Habituellement, une classe a plusieurs constructeurs qui se surchargent les uns les autres, mais ils doivent avoir un nombre ou des types de paramètres différents.

Notez que les constructeurs sont souvent explicitement spécifiés par l’utilisateur dans n’importe quelle classe légèrement complexe. Néanmoins, le constructeur par défaut est généré automatiquement par le compilateur lorsque l’utilisateur ne définit aucun constructeur. Le constructeur par défaut est généralement celui qui ne prend aucun argument, et il est appelé pour l’initialisation par défaut de la classe. Notez, cependant, qu’un constructeur par défaut généré par le compilateur est formellement appelé constructeur par défaut synthétisé. Ce dernier est spécifiquement inféré pour chaque classe en fonction de ses membres de données, et il initialise les membres en utilisant l’initialiseur en classe ou en utilisant la valeur par défaut. Ainsi, les constructeurs générés automatiquement ne sont pas la solution universelle, mais ils fonctionnent correctement pour des structures de classes simples.

Dans l’exemple suivant, nous avons défini une classe MyClass1 avec deux constructeurs. Notez que le premier ne prend aucun argument, ce qui implique qu’il s’agit d’un constructeur par défaut, mais nous avons quand même spécifié un mot-clé default. Ce dernier indique au compilateur que ce constructeur spécifique doit être celui par défaut. Généralement, un compilateur ne génère pas de constructeur par défaut si l’utilisateur définit un constructeur. Dans ce cas, un utilisateur doit explicitement demander la désignation default pour la fonction constructeur donnée.

Le deuxième constructeur de MyClass1 prend une seule valeur string comme argument et initialise le membre de données name avec elle. Il imprime le littéral de chaîne spécial au flux cout uniquement pour rendre le moment d’exécution de la fonction visible pour l’observation. La création de l’objet m2 déclenche celle du constructeur. L’objet m1 est initialisé avec le constructeur par défaut, et puisque le compilateur lui-même génère ce dernier, nous ne voyons aucune chaîne imprimée sur le flux cout.

#include <iostream>
#include <utility>

using std::cout;
using std::endl;
using std::string;

class MyClass1 {
 private:
  string name;
  string nickname;

 public:
  MyClass1() = default;
  explicit MyClass1(string n) : name(std::move(n)) {
    cout << "Constructor 1 is called" << endl;
  };

  string getName() { return name; }

  string getNickname() { return nickname; }

  ~MyClass1() { cout << "Destructor is called" << endl; }
};

int main() {
  MyClass1 m1{};
  cout << m1.getName() << endl;
  cout << m1.getNickname() << endl;
  cout << "------------------" << endl;

  string n1("Maude");
  MyClass1 m2(n1);
  cout << m2.getName() << endl;
  cout << m2.getNickname() << endl;
  cout << "------------------" << endl;

  return EXIT_SUCCESS;
}

Production:

------------------
Constructor 1 is called
Maude

------------------
Destructor is called
Destructor is called

Implémenter plusieurs constructeurs de classes à l’aide de la surcharge en C++

MyClass1 a le deuxième membre de données string appelé nickname. Supposons que nous créions un autre constructeur qui prenne une seule valeur string et la définisse pour initialiser le nickname. Dans ce cas, le compilateur lèvera l’erreur que nous ne pouvons pas surcharger les fonctions avec les mêmes paramètres. Ainsi, nous devons définir un autre constructeur, par exemple, nous avons choisi le constructeur qui prend deux références string et initialise les deux membres de données. Lorsque l’extrait de code suivant est exécuté, nous pouvons voir que le deuxième constructeur a été exécuté.

Les constructeurs ont des caractéristiques beaucoup plus détaillées, et nous n’avons présenté que les principales caractéristiques dans cet article. D’autres fonctions spéciales contiennent le mot - constructor dans leurs noms, comme move-constructor et copy-constructor. Ces deux font partie d’opérations spéciales appelées collectivement contrôle de copie. Notez que les destructeurs conduisent le contraire de ce que font les constructeurs. À savoir, ils désallouent les membres de la classe, et ils sont généralement appelés automatiquement lorsque l’objet sort de la portée. On peut facilement observer le comportement des appels constructeur-destructeur avec les extraits de code donnés.

#include <iostream>
#include <utility>
#include <vector>

using std::cout;
using std::endl;
using std::string;

class MyClass1 {
 private:
  string name;
  string nickname;

 public:
  MyClass1() = default;
  explicit MyClass1(string n) : name(std::move(n)) {
    cout << "Constructor 1 is called" << endl;
  };

  // ERROR: Does not Compile
  //    MyClass1(string nk) : nickname(nk) {
  //        cout << "Constructor 3 is called" << endl;
  //    };
  MyClass1(string &n, string &nk) : name(n), nickname(nk) {
    cout << "Constructor 2 is called" << endl;
  };

  string getName() { return name; }

  string getNickname() { return nickname; }

  ~MyClass1() { cout << "Destructor is called" << endl; }
};

int main() {
  string n1("Maude");
  string n2("Bibi");

  MyClass1 m4(n1, n2);
  cout << m4.getName() << endl;
  cout << m4.getNickname() << endl;
  cout << "------------------" << endl;

  return EXIT_SUCCESS;
}

Production:

Constructor 2 is called
Maude
Bibi
------------------
Destructor is called
Destructor is called
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++ Class