L'explorateur de classes

Geronimo

- Titre : L'explorateur de classes

- Auteur : Geronimo

- Parution : 13 avril 2002

- Mise à jour : 10 mars 2013

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2013 Geronimo. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Introduction

- II. Prérequis

- III. Utilisation basique

- IV. Ajout d'un champ

- V. Ajout d'une propriété

- VI. Ajout d'une méthode

- VII. Autres fonctions annexes

- VIII. Ce qu'il faut retenir…

- IX. Conclusion

I - Introduction

Cet article s'adresse plus spécialement aux débutants. En effet, Borland C++ Builder 5 comporte un explorateur de classes dont l'utilité n'est pas forcément évidente pour un néophyte qui le désactivera vite pour avoir plus d'espace libre. Personnellement, je l'utilise très souvent, vous allez voir pourquoi.

Cet explorateur de classes est un outil très utile. Il permet tout d'abord d'avoir constamment sous les yeux la liste des classes et de leurs membres afin de pouvoir les atteindre d'un double-clic. Ensuite, on peut l'utiliser pour rajouter facilement des champs (membres) et propriétés (pour les composants) à une classe donnée. Enfin, il permet d'ajouter facilement une méthode à une classe sans avoir à taper (ou copier-coller !) séparément la déclaration de la fonction et son implémentation.

Tous ces avantages en font un outil à ne pas négliger.

II - Prérequis

Ce didacticiel a été écrit pour Borland C++ Builder 5. L'explorateur de classes de Borland C++ Builder 5 ayant été remplacé par un Object TreeView dans Borland C++ Builder 6, je ne sais pas si les fonctions décrites ici pour BCB5 existeront toujours dans celui-ci.

Pour suivre les explications de ce document, ouvrez tout simplement dans C++ Builder un projet comportant au moins une classe : une application Windows simple qui comprend la classe TForm1, par exemple.

III - Utilisation basique

L'utilisation basique de cet explorateur de classes est l'utilisation éponyme : explorer les classes de votre projet.

L'explorateur de classes permet de différencier facilement les différents objets que vous pouvez avoir dans votre projet, et cela grâce à une légende que je ne reproduirai pas ici, car elle est accessible en appuyant tout simplement sur la touche [F1] dans l'explorateur de classes, puis sur le lien Légende de l'explorateur de classes. Ainsi, chaque type d'objet : classe, structure, fiches, etc. peut être identifié facilement grâce à une petite icône, de même que les membres : champ (public, privé, protégé), méthode (publique, privée…), constructeur, destructeur, opérateur (public…).

Un double-clic sur un de ces objets place l'éditeur dans le fichier en-tête correspondant, en face de la déclaration correspondante. Dans le menu contextuel de cet explorateur de classes, vous pouvez vous rendre directement à l'implémentation pour une méthode ou un opérateur. Dans ce cas, C++ Builder ouvrira le fichier source nécessaire et vous placera à hauteur de l'en-tête de la fonction.

IV - Ajout d'un champ

Un champ est un membre tout simple d'une classe, qui n'est ni une fonction (méthode ou opérateur) ni une propriété.

Dans le menu contextuel de l'explorateur de classes, cliquez sur Nouveau champ pour accéder à cette fonction, qui n'est pas à négliger, surtout si vous avez de gros fichiers à en-tête. En effet, elle permet de placer un membre rapidement dans la bonne partie de la classe selon la visibilité que vous choisissez. Choisissez un nom, une classe parente, un type et une visibilité : Public et le champ sera accessible pour toutes les fonctions des autres classes. Private pour protéger votre membre : seules les méthodes (fonctions membres) de la même classe ou les fonctions amies pourront y accéder. Protected, comme Private à la différence que les classes qui dérivent de la classe parent pourront y accéder. Pour Published, consultez l'aide. Validez avec OK et votre champ est placé au bon endroit dans la classe choisie.

V - Ajout d'une propriété

Les propriétés étant un sujet très vaste, leur fonctionnement ne sera pas décrit en détail dans ce document.

Pour la propriété, vous pouvez choisir son nom dans le champ Propriété, la classe à laquelle elle appartiendra dans le champ Ajouter à la classe, et enfin son type dans le champ Type. Choisissez ensuite sa visibilité (regardez les explications données précédemment pour l'insertion d'un champ). Ensuite viennent les caractéristiques propres aux champs.

Une propriété peut se voir attribuer des méthodes Get et Set qui sont appelées lorsque la propriété est respectivement lue et modifiée. Dans les champs Lecture et Écriture, vous pouvez donc choisir les méthodes correspondantes préexistantes. Si elles n'existent pas, tapez leur nom et cochez les cases Créer la méthode Get et/ou Créer la méthode Set. Vous pouvez alors choisir dans quel fichier les implémenter.

Une méthode Get ou Set peut être implémentée à l'aide d'un membre de la même classe. Dans ce cas, c'est ce membre qui sera lu ou modifié lorsque la propriété sera lue ou modifiée par l'intermédiaire de ces fonctions. Pour que BCB5 génère le code des fonctions pour vous afin qu'elles utilisent un membre spécifique, vous devez alors cocher les cases Implémenter Get avec le membre et Implémenter Set avec le membre pour choisir des membres existants.

Cocher la case Créer le champ permet de créer un champ qui sera utilisé, soit pour implémenter l'une (ou les deux) méthode(s) Get et Set, soit directement : lorsque la propriété sera lue, c'est ce champ qui sera lu si vous cochez la case Utilisez ce champ pour le spécificateur Read, lorsque la propriété sera modifiée, ce sera ce champ qui sera modifié si vous cochez la case Utilisez ce champ pour le spécificateur Write.

La dernière partie permet de gérer les paramètres des propriétés tableaux. Consultez l'aide de BCB5 pour obtenir des informations sur ce sujet.

VI - Ajout d'une méthode

C'est cette partie que je vais traiter le plus en détail, car c'est à mes yeux la plus utile.

Vue de la boite de dialogue « Nouvelle méthode… »

Choisissez la classe dans l'explorateur et cliquez dessus avec le bouton droit de la souris. Sélectionnez Nouvelle Méthode.

Remplissez le champ Nom de méthode (sauf si vous souhaitez créer un constructeur ou destructeur). Choisissez ensuite à quelle classe vous souhaitez ajouter cette méthode dans le champ Ajouter à la classe. Enfin, remplissez le champ Arguments à l'aide des arguments de la fonction. Placez-les tels que vous les auriez mis dans l'en-tête de la fonction, avec leur nom surtout, mais sans parenthèses. Par exemple,

AnsiString Text, int Length

Ensuite, choisissez le type de méthode. Trois choix sont disponibles ; cochez Fonction afin de créer une fonction membre ; cochez Constructeur pour créer un constructeur pour la classe choisie. Dans ce cas, vous n'avez pas à choisir le nom de la fonction, car c'est celui de la classe. Enfin, cochez Destructeur si vous souhaitez créer un destructeur pour la classe sélectionnée. N'oubliez pas que vous pouvez créer plusieurs constructeurs et plusieurs destructeurs pour une même classe.

class TPays
{
TPays(); // Constructeur par défaut
TPays(AnsiString Name, int Population); // Constructeur
TPays(AnsiString Name); // Autre constructeur
~TPays(); // Destructeur
}

Le champ Résultat de la fonction type de la valeur que retourne la fonction vous permet de choisir l'un des types de base du C++ proposés dans la liste ou bien spécifier celui que vous souhaitez. N'oubliez pas l'astérisque si vous souhaitez retourner un pointeur.

// La fonction malloc est définie comme retournant un pointeur, par exemple :
void *malloc(size_t size);

Pour la visibilité, reportez-vous encore à la partie Ajout d'un champ pour avoir plus d'informations.

Les Directives permettent de mieux contrôler les fonctions.

Si vous cochez abstract, la fonction n'aura pas d'implémentation dans cette classe et sera seulement implémentée dans une classe dérivée. Une fonction abstraite est obligatoirement virtuelle donc la case virtual sera cochée. Le mot-clé abstract n'est pas utilisé en C++, mais est remplacé par le "= 0" après la déclaration de la fonction :

/* FICHIER EN-TETE */
class Toto
{
// ...
// Cette fonction n'aura pas d'implémentation pour cette classe, mais
// seulement dans une classe dérivée.
public:
virtual int get_value() = 0;
// ...
};

class Tata : public Toto
{
int get_value();
};

/* FICHIER SOURCE */
int Tata::get_value() // La fonction est bien implémentée dans la classe Tata
{
//...
}

Si vous cochez la case virtual, la fonction pourra être implémentée dans la classe parente ainsi que dans les classes dérivées :

/* FICHIER EN-TETE */
class Toto
{
// ...
// Cette fonction sera implémentée dans cette classe et dans la classe dérivée
public:
virtual int get_value();
// ...
};

class Tata : public Toto
{
int get_value();
};

/* FICHIER SOURCE */
int Toto::get_value() // La fonction est bien implémentée dans la classe Toto
{
//...
}

int Tata::get_value() // La fonction est bien implémentée dans la classe Tata également
{
//...
}

Avec la directive const, la méthode que vous créez ne pourra modifier aucun membre de sa classe qu'elle considèrera comme constant :

/* FICHIER EN-TETE */
class Toto
{
int nombre;
void fonction_quelconque(int nb) const;
};

/* FICHIER SOURCE */
void Toto::fonction_quelconque(int nb) const
{
nombre = nb; // Erreur du compilateur
}

La convention d'appel __fastcall permet de créer des fonctions plus rapides. En effet, chacun des trois premiers arguments de la fonction tient dans un registre du processeur, il y sera placé ce qui signifie que son accès sera extrêmement rapide. Selon l'aide, "toutes les fonctions membres de classe fiche doivent utiliser la convention __fastcall".

Le champ Gestionnaire de messages permet, si vous le désirez que votre fonction gère un message Windows. Attention, votre fonction doit avoir un seul argument qui doit être du type TMessage.

Les champs suivants permettent de régler certains détails de l'implémentation de la fonction. Si la case Appel hérité est cochée, BCB5 créera dans l'implémentation de la fonction le code appelant la fonction de même nom de la classe dont elle hérite. La case Inline étant cochée, la directive inline sera ajoutée à la fonction. Chaque appel de la fonction sera remplacé par son code. À éviter pour de grosses fonctions !!! Avec la directive Inline implicite, au lieu d'ajouter la directive inline, vous implémenterez votre fonction directement dans le fichier en-tête. Le résultat sera aussi une fonction "en ligne";

/* FICHIER EN-TETE */
class Toto
{
void fonction_chose()
{
//...
}
};

Fichier : vous pouvez choisir dans quel fichier implémenter cette méthode. En effet, il est possible de subdiviser une classe en plusieurs fonctions, pour cela, consultez les excellents Conseils & exemples de Gilles Louise.

VII - Autres fonctions annexes

Les fonctions que je vais détailler brièvement dans cette partie sont moins utiles que les précédentes, mais il est toujours bon de connaître leur existence.

Lorsque vous travaillez sur de grands projets qui ont beaucoup de fichiers d'en-tête, il n'est pas rare d'avoir plusieurs centaines de classes au total dans l'explorateur. Il peut être agréable d'en réduire le nombre afin que BCB5 n'affiche que les classes qui concernent le fichier en cours. Utilisez pour cela à nouveau le menu contextuel, puis cliquez sur Type de vue et Fichier en cours.

Les classes sont représentées hiérarchiquement dans un arbre. Pour déplier (ou replier) les branches de l'arbre, il suffit de cliquer sur le + (ou le -) situé à gauche de chaque élément. Mais il peut être utile de tout déplier ou replier. Pour cela, utilisez la commande Nœud - Tout développer ou Nœud - Tout replier.

Si l'éditeur n'est plus visible, cliquez sur Voir l'éditeur et celui-ci réapparaîtra, ayant le focus.

VIII - Ce qu'il faut retenir…

- Cliquer sur une classe, puis sur Nouvelle méthode… permet de créer rapidement, d'un seul coup, implémentation et déclaration d'une fonction.

- Vous pouvez modifier quelques options de l'explorateur de classes dans Outils - Options d'environnement.

- L'explorateur de classes permet de créer des méthodes semblables « à la chaîne » en utilisant le bouton Appliquer au lieu de bouton OK ce qui ne ferme pas la boite de dialogue, mais crée le code. Par exemple, vous pouvez créer plusieurs constructeurs en utilisant ce bouton Appliquer et en changeant juste les arguments entretemps.

- L'explorateur de classes peut paraître encombrant. Pour cette raison, je l'ai ancré sous l'inspecteur d'objets afin de l'avoir toujours sous la main, sans qu'il ne m'occupe une surface trop importante.

L'explorateur de classes ancré sous l'inspecteur d'objets. À droite, la fenêtre d'édition et en bas les messages.

- Si l'explorateur de classes n'est plus visible, vous pouvez le faire réapparaitre à tout moment grâce à la commande Voir - Explorateur de classes.

IX - Conclusion

Cet outil qu'est l'explorateur de classes peut sembler peu utile au premier abord. Mais ses fonctions, pourtant simples, permettent de développer plus rapidement ses classes.

Cependant, si vous souhaitez développer de grandes classes, très organisées, ou avoir un programme plus puissant, un outil UML sera préférable. Personnellement, j'utilise ClassBuilder (gratuit) qui permet de créer facilement et rapidement de grandes classes, tout en étant synchronisé avec BCB (quand vous passez de l'un à l'autre, les modifications sont reflétées).

Ceci était mon premier article ; je pense qu'il y en aura d'autres si vous l'avez apprécié et qu'il vous a rendu service. Toutes les critiques constructives sont acceptées.

Geronimo.
geronimooo@ifrance.com.