Mandragor


Les classes.

Introduction à la notion de classe

La notion de classe est l'innovation du C++ par rapport au C la plus importante. En effet, c'est cette présence d'objets qui permet de parler du C++ comme d'un langage objet.

Avant d'aller plus loin, voyons ce qu'est un objet. Et bien, un objet est un outil informatique qui sert a simuler l'existence de "matériel physique" dans un programme. Un objet peut être aussi bien une porte, une fenetre, qu'un chien ou encore une entrée dans un carnet d'adresse. L'objet est une notion de laquelle découlent les notions d'héritage, de polymorphisme, de liste chaînée, de template (nous verrons tout cela plus tard)...

En attendant, nous allons un peu plus voir ce qu'est un objet et comment on s'en sert, et a quoi cela sert. Fondamentalement on peut séparer un objet en deux parties, ses caractéristiques et ses "option de mouvement". Je m'explique, prenons un objet chien. Le chien a un nom, une race, une position (les caractéristiques), le chien peut mourrir, aboyer, marcher (les options de mouvement)...

Concrètement, comment va t'on simuler tout cela? Et bien on va intégrer a la déclaration de l'objet des variables de type primaires (int, char, float...) ou étendues (autres objets) pour simuler les caractéristiques, et des fonctions pour simuler les "options de mouvements". Une classe va etre le "Prototype" des objets. ainsi par exemple nous allons créer une classe Porte; une fois la declaration de la classe écrite, on pourra créer (on expliquera plus en detail ce terme après) des objets de type Porte, car alors Porte sera devenu un nouveau type etendu de variables.

En C++, lorsque vous écrivez une structure, il n'est plus nécessaire d'utiliser typedef pour definir un nouveau type de variable; le C++ le fait maintenant automatiquement.

Un exemple plus concret.

Nous parlions au-dessus d'une éventuelle classe Porte. Alors allons-y, écrivons la: (programme commenté)

  //class est le mot clé de déclaration d'une classe (comme struct pour les structures)
  class Porte
  {
    public: // Correspond a l'étiquette de protection, mettez public, on en reparlera plus tard

      // Les caractéristiques de la classe
      bool etat; // la porte est elle ouverte ou fermée??

      // les possibilités de la classe
      void ouvrir();
      void fermer();
  };

  /* Remarquez le ; a la fin de la déclaration comme pour les structures. On pourrait
     aussi au même endroit déclarer tout de suite un objet de type Porte en faisant
     } porte_du_jardin;
  */

  void Porte::ouvrir (void)
  {
    /* Ceci est le corps de la fonction ouvrir, membre de la classe Porte.
       C'est cette fonction qui sera appelée lorsque l'on apellera la
       fonction ouvrir() d'un objet de type Porte.
    */
    cout << "La porte s'ouvre" << endl;
    etat=true;
  }

  void Porte::fermer (void)
  {
    cout<<"La porte se ferme"<<endl;
    etat=false;
  }

On a donc notre class Porte, porte qui peut s'ouvrir et se fermer. Comment allons nous appeler la fonction ouvrir()? Nous accédons aux attributs de l'objet de la même façon que nous accédons aux champs des structures.


  int main (void)
  {
    Porte portedupremier; //aller savoir pourquoi porte du premier...:)
    portedupremier.ouvrir();
    portedupremier.fermer();
    return 0;
  }

Ce programme s'exécutera en inscrivant:

la porte s'ouvre la porte se ferme

Et on accède aux variables de la classe comme les fonctions: portedupremier.etat vaut true si la porte est ouverte, et false si elle est fermée.

Classe et pointeur.

Lorsque l'on accède à un objet par un pointeur, on devra utiliser l'operateur '->' a la place de l'operateur '.' (utilisé pour les accès par variable "normaux"). En effet, comme pour les structures, on différencie les deux modes d'accés. Ainsi, on accedera aux donnees membres de la facon suivante:

  <nom_de_l'objet> -> <nom_de_la_donnee>

Le pointeur this.

Le pointeur this est utilisé de façon interne par le compilateur, c'est lui qui permet que deux classes aient les même champs. Il est à savoir que vous pouvez l'utiliser vous aussi dans vos programmes. Quand on a fait notre void Porte::ouvrir(void);, le compilateur a traduit par void ouvrir (Porte *this); et le corps de cette fonction est devenu:

  void ouvrir (Porte *this)
  {
    cout << "La porte s'ouvre" << endl;
    this->etat = TRUE;
  }

Le pointeur this est surtout utilisé lors de l'utilisation de variables locales et de la classe qui ont le même nom. car sinon le compilateur utiliserait la variable passée en arguments et npn la variable de l'objet. Ainsi on aurait pu écrire:

  void Porte::fermer (void)
  {
    cout<<"La porte se ferme"<<endl;
    this->etat=false;
  }

Personnellement, j'utilise beaucoup le pointeur this, en fait, je le met à chaque fois. car je trouve qu'il est ainsi plus facile de distinguer une variable locale/globale/argument des variables qui seront conservées à l'interieur de l'objet.