Constructeur (programmation)

Un constructeur est, en programmation orientée objet, une fonction particulière appelée lors de l'instanciation. Elle permet d'allouer la mémoire nécessaire à l'objet et d'initialiser ses attributs.

constructeur PMI

Si le langage l'autorise, la surcharge est possible et les constructeurs se différencient par le nombre et le type des paramètres passés et renvoyés mais aussi par le formalisme employé. Dans de nombreux langages, on distingue certains constructeurs en particulier :

  • le constructeur par défaut n'a aucun argument ;
  • le constructeur par recopie a un unique argument du même type que l'objet à créer (généralement sous forme de référence constante) et il recopie les attributs depuis l'objet passé en argument sur l'objet à créer.

Ces deux constructeurs ont souvent une définition attribuée par défaut par le compilateur. Le constructeur par défaut n'a alors aucun effet ; le constructeur de recopie par contre recopiera les valeurs de tous les membres de l'objet donné vers l'objet courant. Ceci peut s'avérer particulièrement dangereux, spécialement dans le cas où des pointeurs sont alloués par le constructeur et libérés par le destructeur.

En Java

modifier

En Java, new est un opérateur unaire de construction qui crée un nouvel objet ou un nouveau tableau.

Pour créer un nouvel objet, le mot-clé new doit être suivi d'une méthode qui soit un constructeur. Par exemple, on pourra avoir :

MaClasse obj; 
    ... 
obj = new MaClasse(5, "bonjour");

si toutefois la classe MaClasse a un constructeur qui possède deux paramètres : un entier et une chaîne de caractères.

Pour créer un nouveau tableau, on peut par exemple écrire :

String[] arguments = new String[10];
    // ou bien : 
int[][] uneMatrice = new int[4][5];
    // ou encore : 
int[][] quatreLignes = new int[4][];

En C++, le constructeur est une fonction membre publique de la classe portant le même nom que celle-ci. Il est appelé lors de la déclaration de l'objet ou lors de l'utilisation du mot-clé new (lors d'une allocation sur le tas). Le constructeur peut utiliser la syntaxe constructeur(argument) : variable(argument) pour initialiser les variables.

#include <memory>

class Object
{
    public :
        Object ();                      // Constructeur par défaut
        Object (int n) : nombre(n){};   // Constructeur paramétrique
        Object (const Object&);         // Constructeur par recopie
        ~Object ();                     // Destructeur
        int nombre;
};

int main ()
{
    { //allocation sur la pile
        Object obj;       // Appel du constructeur par défaut pour obj
        Object obj2(obj); // Appel du constructeur par recopie pour obj2
        Object obj3(4);   // Appel du constructeur paramétrique pour obj3
    } // Appel du destructeur pour obj, obj2 et obj3 lors de la sortie de la portée
    
    { //allocation sur le tas
        Object * p_obj = new Object(27); // Appel du constructeur paramétrique pour créer un Object sur le tas
        //et initialisation de p_obj à l'adresse de cet Object
        //si le pointeur sortait de la portée ici, l'adresse de l'Object déclaré sur le tas
        //serait perdue et ainsi de la mémoire ne serait pas libérée
        delete p_obj; // Appel du destructeur pour détruire l'objet pointé par p_obj
        //et libération de la mémoire allouée
    }
    
    { //allocation sur le tas grâce à un pointeur intelligent
        std::unique_ptr<Object> p_obj2; //on déclare un objet sur le tas qu'on a pas besoin de supprimer manuellement
        p_obj2 = new Object(42); //Appel du constructeur paramétrique pour créer un Object sur le tas
        //et initialisation de p_obj2 à l'adresse de cet Object
    } //appel du destructeur de p_obj2 qui lui même appelle le destructeur de l'Object pointé et libère la mémoire lors de la sortie de la portée
}

Exemple de constructeur en C# :

public class MaClasse
{
    private int a;
    private string b;

    // Constructeur
    public MaClasse() : this(42, "string")
    {
    }

    // Surcharge d'un constructeur
    public MaClasse(int a, string b)
    {
        this.a = a;
        this.b = b;
    }
}
// Instanciation d'un objet à l'aide du constructeur 
MaClasse c = new MyClass(42, "string");

Il existe par ailleurs en C# des constructeurs statiques, qui permettent d'initialiser une donnée statique et d'effectuer une action particulière devant être effectuée une seule fois. Les constructeurs statiques sont appelés implicitement avant qu'une instance ne soit créée. Tout appel à une classe (appel statique ou constructeur), déclenche l'exécution du constructeur statique.

Exemple d'utilisation d'un constructeur statique :

public class MaClasse
{
    private static int _A;

    // Constructeur statique
    static MaClasse()
    {
        _A = 32;
    }

    // Constructeur standard
    public MaClasse()
    {

    }
}
// Instanciation d'un objet à l'aide du constructeur 
// juste avant l'instanciation
// Le constructeur statique est exécuté, _A prend la valeur 32
MaClasse c = new MaClasse();

Critique

modifier

Dans les langages tels Java, l'appel à un constructeur est équivalent à l'appel d'une méthode statique, ce qui rend plus difficile l'écriture de tests unitaires pour une méthode. L'injection de dépendance permet au programmeur de ne plus devoir écrire aucun appel de constructeur car le framework d'injection de dépendance s'en charge à sa place.

Voir aussi

modifier