Table des matières
<<Retour à la page principale du cours
Le code de la route de la conception de projet
Votre note va dépendre de ces points.
Outils
- Editeur de code propre (Emacs, Vi, Scite, CodeBlocks, etc. oubliez les éditeurs de texte) qui doit comporter :
- Indentation et code couleur
- Compilation dans l'éditeur avec lien direct sur les erreurs
- Les plus : auto-complétion lors de la frappe, recherche de définition de variable, etc.
- Makefile au minimum et éventuellement projet CodeBlocks. Dans tous les cas, on ne compile plus dans le terminal!
- Utiliser un débugeur (par ex. gdb), un profiler (par ex. gprof ou valgrind)
- Gestion du code sous GitLab
- Code documenté sous Doxygen
- Un projet comprend un README.txt expliquant comment l'utiliser et décrivant ce qu'il fait
Règles de conception
- Un programme est constitué de modules (c-à -d .h/.cpp)
- Un module est habituellement constitué d'une seule classe : par exemple
class Image
donne le module Image.h/.cpp - Pour chaque classe, définissez un ensemble de fonctions membres travaillant sur celle-ci. Ces fonctions membres auront un nom explicite et standardisée : ex. fait de un ou plusieurs mots indiquant ce que fait la fonction. Par exemple :
void effacer(const Pixel & couleur); void sauver(const string & filename) const;
- Ecrivez des accesseurs get quand cela est nécessaire. Il ne devraient y avoir que très peu de mutateurs set et ils font des vérifications importantes. Par exemple :
void setPix(const unsigned int x, const unsigned int y, const Pixel & couleur); // modifie la couleur du pixel de coordonnées (x,y) // si x ou y ne sont pas valides, la procédure s'arrête (par exemple avec un assert)
- A part les fonctions du module, aucune autre partie du code n'accède directement aux champs de la classe. Par exemple le module TraitementImage n'accède pas directement à la donnée membre
dimx
d'une image mais utilise l'accesseur.
Les pointeurs
Vous pouvez quasiment vous passer des pointeurs si vous utilisez des std::vector pour stocker vos éléments. Moins de pointeurs = moins de bug ! Notamment attention à ce bug :
class A { pubic: A() : pi(new int[10]) { for(int i=0;i<10;i++) pi[i]=i; } ~A() { delete[] pi; } private: int* pi; }; int truc() { A a; // a.pi pointe sur un tableau A aa; // aa.pi pointe sur un autre tableau aa = a; // aa.pi pointe maintenant sur le tableau a.pi : car le "=" recopie a dans aa. // Le 1er tableau de aa n'est plus accessible, ce qui est déjà une grosse erreur mais ne fait pas planter. } // Le destructeur de a détruit son tableau a.pi. // Le destructeur de aa détruit également le même tableau car aa.pi et a.pi sont les mêmes int machin() { A a; std::vector<A> tabA; tabA.push_back(a); } // Même erreur que précédemment
Pour résoudre ce problème il faut soit écrire un operator= et un constructeur par copie (1ere solution) ou ne pas utiliser de pointeur (2e solution).
Solution 1 :
class A { pubic: A() : pi(new int[10]) { for(int i=0;i<10;i++) pi[i]=i; } A(const A& a) : pi(new int[10]) { for(int i=0;i<10;i++) pi[i] = a.pi[i]; } const A& operator=(const A& a) { for(int i=0;i<10;i++) pi[i] = a.pi[i]; } // recopie du tableau, pas du pointeur ~A() { delete[] pi; } private: int* pi; };
Solution 2 (vraiment plus courte) :
class A { pubic: A() { for(int i=0;i<10;i++) tabi.push_back(i); } ~A() {} private: std::vector<int> tabi; };
Règles de programmation
- Faites des vérifications avec assert
- Passage de paramètres irréprochable : les paramètres sont quasiment toujours passés par référence
- si en mode donnée ⇒
const Type &
ouType
- si en mode donnée-résultat ⇒
Type &
void Image::fonctionInOut(Pixel &); // donnée-résultat (IN-OUT) void Image::fonctionIn(const Pixel &); // donnée (IN)
- Mettez des const partout où vous pouvez
- Définissez et respectez une norme sur les noms de variable et donnez du sens au nom de vos variables
- Initialisation de toutes les variables
Gestion de la mémoire
- Allocation dans le tas différent de la pile (relire le cours de LIFAP3)
- Pour toute allocation mémoire dans le tas, il faut absolument une désallocation à un moment
- Avec valgrind tout doit être propre!