Projet : Remarques après la première séance

17 mai 2001

1   Les classes Mur et Labyrinthe dans un même fichier .H et un même fichier .C

Au départ nous avions pensé regrouper les classes Mur et Labyrinthe dans les fichiers Labyrinthe.H et Labyrinthe.C, car d'une part la classe Mur est assez petite, et d'autre part les deux classes sont assez dépendantes l'une de l'autre. Ceux qui veulent néanmoins séparer les deux classes en des fichiers distincts (ce qui est en principe recommandé) peuvent bien sûr le faire. Ils devront simplement rajouter une ligne dans le fichier Makefile pour indiquer à gmake de compiler aussi le fichier Mur.C.

2   Rappel sur les tableaux d'objets

2.1   Tableau de pointeurs sur des objets

Pour créer un tableau d'objets de type A il est conseillé de créer en fait un tableau de pointeurs sur des objets de type A. Découvrons ensemble le problème sur un exemple :

class A {
public:
  A(int i) {};
};

int main(){
  A mon_tableau[7];
}
Ce programme n'est pas correct et le compilateur va générer une erreur. En effet, dans chaque case du tableau le compilateur doit construire un objet de type A, il doit donc logiquement se servir d'un constructeur. Comme il n'est pas possible de passer des arguments au constructeur quand on construit un tableau, le compilateur va chercher à utiliser un constructeur qui ne prend pas d'argument. Or le seul disponible prend un argument (int i), d'ou l'erreur. Une façon de faire serait de définir un constructeur sans argument qui serait utilisé uniquement dans ce genre de situation, ça marche mais c'est assez laid.

Une meilleure solution est de différer la construction des éléments du tableau en déclarant un tableau de pointeurs :
A* mon_tableau[7];
On construit ensuite chaque élément du tableau en utilisant le mot clé new :
mon_tableau[0] = new A(4);
mon_tableau[1] = new A(2);
... etc...

2.2   Comment déclarer un tableau quand on ne connaît pas encore sa taille

Au lieu de :
A mon_tableau[10];
On écrit :
A* mon_tableau;
puis quand on connait sa taille :
mon_tableau = new A[10];
Ici on a un tableau d'objets de type A. Pour éviter le problème dont on a parlé dans la section précédente, il est préférable d'avoir un tableau de ``pointeurs'' sur des objets de type A. En combinant les deux approches on obtient le schéma suivant :
A** mon_tableau; // déclaration du tableau

mon_tableau = new A*[10]; // allocation de mémoire quand on connaît sa
                          //taille

mon_tableau[0] = new A(4); // construction de chaque élément
mon_tableau[1] = new A(2);
... etc...

3   Compilation partielle du programme

Pour compiler un seul fichier du programme et obtenir les éventuelles erreurs, on peut taper la commande de compilation suivante :
g++ -c exemple.C
ou, s'il y a plusieurs fichiers :
g++ -c exemple1.C exemple2.C
S'il y a une fonction main dans l'un des fichiers .C, on peut aussi enlever l'option -c à la ligne de commande pour obtenir un exécutable (a.out si on ne le renomme pas avec l'option -o suivie du nom désiré).

4   Utilisation de la classe Dessin

Pour tracer un dessin dans un fichier au format postscript (.ps) en utilisant la classe Dessin, on doit suivre le schéma suivant :
  1. créer un objet dessin de type Dessin
  2. ajouter des segments à ce dessin en appelant une des méthodes dessine sur cet objet. Ces segments seront stockés dans le dessin.
  3. imprimer tous les segments stockés dans le dessin dans un fichier en appelant la méthode enregistre sur l'objet dessin.
Remarque
Pour ajouter un seul segment, on peut utiliser la méthode suivante (voir Dessin.H) :
// Ajoute un segment au dessin.
  void dessine(Segment segment);
Pour ajouter une ligne brisée (c-à-d des segments de droite liés entre eux), on peut utiliser la méthode suivante (voir Dessin.H) :
// Ajoute une ligne cassée au dessin.
  void dessine(double points[][2],int nbre_points);
points est ici un tableau contenant les coordonnées x et y des points de cassure de la ligne brisée et nbre_points la taille de ce tableau. Pour dessiner un triangle, on peut par exemple l'utiliser ainsi :
double points[][2] = {{0,0},{0,1},{1,1},{0,0}};
dessin.dessine(points,4);

5   Passage par référence

Rappelez-vous qu'à chaque fois qu'une fonction modifie un de ses arguments celui-ci doit être passé soit par référence, soit sous forme d'un pointeur. Dans le projet ce sera certainement le cas pour les fonctions dessiner des classes Mur et Labyrinthe qui modifient l'argument de type Dessin passé en argument.


This document was translated from LATEX by HEVEA.