Académique Documents
Professionnel Documents
Culture Documents
2018/2019
Chapitre 5
1 ATEL
Les patrons (ou template) permettent de créer des fonctions et
des classes génériques, c’est à dire indépendantes d’une classe
particulière.
2
Pour expliquer les fonctions patrons, il n’y a pas mieux que de
considérer un exemple très connu en programmation à savoir le
problème de tri.
Le problème consiste généralement à trier un tableau
contenant N éléments de type donné.
En programmation classique, on est amené à créer autant de
sous-programmes de tri que de type de données à trier.
Les fonctions patrons vont nous permettre d’écrire un seul
sous-programme avec un type quelconque et c’est le
compilateur qui se chargera de générer le sous-programme
approprié à chaque type de données utilisé.
3
Exemple
int main ()
{ int entier [ ] = { 45, 21, 3, 56, 68, 4} ;
trier (entier , 6) ;
float reel [ ] = { 1.5, 2.5, 3.6, 42.5, 36.5, 8.5, 4.2} ;
trier (reel , 7) ;
etc….
}
5
Mais si on veut appeler trier pour trier de nouveau type tels que des personnes,
il suffit de définir la classe correspondante et de surcharger l’opérateur ‘<‘ .
Exemple
Définir une classe personne ayant un nom et un âge. Définir l’opérateur < pour
comparer le nom et en cas d’égalité utiliser l’âge.
class pers
{ public :
string nom ;
int age ;
pers ( string n = “ “ , int a = 0) //constructeur avec arguments
{ nom = n ;
age = a ;
}
6
bool operator < ( pers & p)
{ //int res = strcmp (nom, p.nom) ;
if ( nom < p.nom ) return true;
if ( nom>p.nom ) return false;
return age < p.age ? 1 : 0;
}
};
int main ( )
{
pers tab[ ] = { pers(” ALI ”, 28) , pers(” MOHAMED ”, 18) ,
pers(” FETHI ”, 32) };
trier (tab, 3);
}
7
En programmation, on a souvent besoin de tableaux ordonnés, de listes
chaînées, … Les types des éléments de ces structures sont variés. Pour
utiliser le même code quelque soit le type on peut utiliser les classes
patron ou classes génériques ou classes conteneurs.
Une classe patron est une classe très générale qui va traiter des objets
d’une classe X.
Exemple
Nous allons définir une classe générique « tableau » qui aura :
Un constructeur qui allouera un tableau d’une manière dynamique.
Un destructeur qui libèrera la mémoire
Une fonction d’insertion d’un objet dans le tableau
Une fonction d’affichage
8
Pour insérer un objet, on utilisera l’opérateur < que la classe réelle devra
surcharger. L’affichage étant aussi particulier à chaque élément, la classe
réelle doit définir une fonction d’affichage.
9
int insert ( TRUC &obj) // insertion d’un élément dans le tableau tab
{ if (nbe == taille ) return 0 ; //tableau saturé
int i =0;
while (i < nbe && tab[i] < obj ) i++;
for (int j = nbe ; j> i ; j-- )
tab [j] = tab [j-1];
tab[i] = obj;
nbe++;
return 1;
}
void afficher_tab ( ) // fonction permettant d’afficher les objets
{ for ( int i =0 ; i< nbe ; I++)
cout<<tab[i];
}
}; // fin de la définition de la classe patron 10
// définition d’une classe particulière pers
class pers
{ char *nom;
int age;
public :
pers ( char *n = “ “ , int a = 0)// constructeur avec arguments
{ nom = new char [ strlen (n) +1];
strcpy ( nom, n ) ;
age = a ; }
pers ( pers &p) // constructeur par copie
{ nom = new char [ strlen (p.nom) +1];
strcpy ( nom, p.nom ) ;
age = p.age ; }
~pers ( ) { delete [ ] nom ; } // destructeur
11
int operator < ( pers & p)
{ int res = strcmp (nom, p.nom) ;
if ( res < 0 ) return 1;
if ( res > 0 ) return 0;
return age < p.age ? 1 : 0;}
pers & operator = ( pers & p)
{ delete [ ] nom;
nom = new char [strlen (p.nom)+1 ];
strcpy (nom, p.nom);
age = p.age ; }
void Afficher ( )
{ cout << nom <<” (“ << age << “)” << endl ;
}
}; // fin de définition de la classe pers
12
int main ()
{
tableau <pers> p ;
pers toto (« Naoufel » , 17) ;
p.insert (toto) ;
pers p1(” ALI ”, 28) ) ;
p.insert ( p1) ;
p.afficher_tab ( ) ;
}
13