Structures de données IFT Abder Alikacem Espace de nommage Département d’informatique et de génie logiciel Édition Septembre 2009
Plan Spécification Utilisation Implémentation Using namespace
Encapsulation: espace de nommage namespace permet de définir un espace denommage, i.e. un module (un paquetage en Java). Spécification namespace pileDeChar { // interface dans un fichier Pile.h void empiler( char ) ; char depiler() ; bool estVide() ; }
Encapsulation: espace de nommage Utilisation Un fichier Test-pile.C peut alors utiliser l’interface : #include "pile.h" #include int main() { pileDeChar::empiler( ’x’ ) ; if (pileDeChar::depiler() != ’x’) std::cerr << "impossible\n." ; } Le préfixe pileDeChar:: indique que empiler() et depiler() sont ceux du module pileDeChar.
Encapsulation: espace de nommage Implémentation L’implémentation peut être donnée lors de la spécification (dans le fichier Pile.h) : namespace pileDeChar { const int tailleMax = 200 ; char laPile [ tailleMax ] ; int sommet = 0 ; void empiler ( char c ) { //Attention, pas de contrôle de débordement laPile[ sommet ] = c ; ++sommet ; } char depiler() {// Attention, pas de contrôle de débordement return laPile[ --sommet ] ; } bool estVide() {return sommet == 0 ;} }
Encapsulation: espace de nommage Implémentation Il est possible de donner l’implémentation d’une fonction séparément (ici dans Pile.C), en préfixant le nom de la fonction par l’identificateur de son espace de nommage : #include "Pile.h" namespace pileDeChar { const int tailleMax = 200 ; char laPile [ tailleMax ] ; int sommet = 0 ; } int pile_de_char::depiler() {// contrôle de débordement... return pileDeChar::laPile[ --sommet ] ; } void pileDeChar::empiler ( char c ) {... } ; bool pileDeChar::estVide ( ) {... } ;
Encapsulation: espace de nommage Using namespace Il est possible de spécifier que tous les noms doivent également être cherchés dans un namespace donné. Le préfixage par pileDeChar:: peut alors être omis si il n’y a pas d’ambiguïté. int main() { pileDeChar::empiler(’a’); using namespace pileDeChar; depiler(); return 0; }
Encapsulation: espace de nommage Koenig lookup Une fonctionnalité intéressante des espaces de nommage est le “Koenig lookup” : lors d’un appel à une fonction le type des arguments permet parfois de lever l’ambiguïté. Ceci peut être très utile pour faire des fonctions génériques modifiables par la suite (puisque un namespace est une structure ouverte à laquelle il est toujours possible d’ajouter des données ou des méthodes).
Encapsulation: espace de nommage Koenig lookup Exemple #include namespace Listes { struct TypeDeDonnees { std::list valeurs; }; void affiche(TypeDeDonnees l) { std::cout << "Listes\n"; } } namespace Vecteurs { struct TypeDeDonnees { std::vector valeurs; }; void affiche(TypeDeDonnees l) { std::cout << "Vecteurs\n"; } } int main() { Vecteurs::TypeDeDonnees v; // Vecteurs::affiche est trouvée, même sans ‘‘using’’, // grâce à son paramètre de type Vecteurs::TypeDeDonnees. affiche( v ) ; return 0; }