next up previous
Next: Les templates Up: Les classes Previous: Destructeur par défaut

Constructeurs

Il n'existe qu'un destructeur par classe, mais il peut exister plusieurs constructeurs. Ceux-ci ont alors des arguments différents, mais sont formatés de la même façon (même nom, pas de retour). Par exemple:

class Tableau {

  double* tab;
  int n;

 public: 

  Tableau(){
    n = 0;
  }

  Tableau(int a){
    n = a;
    tab = new double[a];
  }


  // autres champs et fonctions membres, destructeur

};

Au moment de la déclaration d'un objet de cette classe, on a alors le choix entre les deux constructeurs:

Tableau A;   // appelle le constructeur sans argument 
             // et initialise donc A.n à 0

Tableau B(5);  // appelle le constructeur avec un argument de type int
               // et alloue donc un tableau de taille 5

Il existe un constructeur particulier, le constructeur par copie. Celui-ci prend comme argument une référence (éventuellement constante) sur un objet de la même classe. C'est ce constructeur qui est appelé lorsque l'on passe à un argument à une fonction et que celle-ci recopie automatiquement cet argument dans une variable locale à elle. Par défaut, ce constructeur recopie un à un les champs de l'objet en argument dans le nouveau. Dans notre cas, il recopierait la valeur du champ n ainsi que la valeur du pointeur tab, c-à-d qu'il créérait un nouveau pointeur vers le même tableau que précédemment. Si l'on préfère que le nouvel objet ne partage pas le même tableau, mais qu'un nouveau tableau soit alloué et que l'on recopie les différentes cases de l'ancien dans le nouveau, il faut donc procéder ainsi:

class Tableau {

  double* tab;
  int n;

 public: 

  Tableau();
  Tableau(int a);

  Tableau(const Tableau& X){
    n = X.n;
    tab = new double[n];
    for (int i = 0; i<n; i++)
      tab[i] = X.tab[i];
  }

  // autres champs et fonctions membres, 
  // dont l'opérateur parenthèses précédemment introduit
  double& operator()(int a);

};

Ainsi, si une fonction f a été déclarée de la façon suivante:

void f(Tableau X);

alors dans le code suivant il y a un appel caché au constructeur par copie:

Tableau A(5);   // appel au constructeur prenant 
                // un int comme argument
for (int i=0; i<A.n; i++)
  A(i) = i+1;

Tableau B(A);  // appel au constructeur par copie
Tableau C = A; // appel au constructeur par copie aussi ! 
               // équivalent à Tableau C(A);

C = A;  // appel à operator= (à ne pas confondre avec le = ci-dessus)

f(A);  // appel au constructeur par copie afin de recopier l'argument

car en effet cette dernière ligne se traduira par:

{
  Tableau X = B;    // appel au constructeur par copie
  ... // bloc écrit dans la définition de la fonction f
}

Attention ! Le symbole = dans une déclaration est un raccourci pour appeler le constructeur par copie, alors que ce même symbole hors des déclarations est l'opérateur = !


next up previous
Next: Les templates Up: Les classes Previous: Destructeur par défaut
Guillaume Charpiat 2006-12-07