Télécharger la présentation
La présentation est en train de télécharger. S'il vous plaît, attendez
Publié parMarcellette Gervais Modifié depuis plus de 10 années
1
Structures de données IFT-2000 Abder Alikacem Espace de nommage Département dinformatique et de génie logiciel Édition Septembre 2009 Département dinformatique et de génie logiciel
2
Plan Espace de nommage Utilisation Implémentation Using namespace
3
Problème de collisions de noms… Quarrive-t-il si 2 fonctions globales différentes ont le même prototype ? // MaLib1.h int f(); // MaLib2.h int f(); class A{}; #include "MaLib1.h" #include "MaLib2.h" int g(){ return 5 + f();//Quel f() ? }
4
Solution: créer des namespaces Namespace : regroupement logique de fonctions, de classes, etc. Possibilité de lui donner un nom: NomDuNamespace::NomDeLEntite Pas d'ambiguïté // MaLib1.h namespace Util{ int f(); } #include "MaLib1.h" #include "MaLib2.h" int g(){ Tp1::A a; return 5 + Util::f(); // Ah, ok } // MaLib2.h namespace Tp1{ int f(); class A{}; } On se sert de l'opérateur d'appartenance ::
5
Using namespace namespace directement accessible : commande using #include "MaLib1.h" #include "MaLib2.h" using namespace Tp1; int h(){ A a; int x = f(); return x + Util::f(); } Par le using, c'est Tp1::f().
6
Encapsulation: espace de nommage namespace permet donc de définir un espace de nommage, i.e. un module (un paquetage en Java). Exemple. Spécification namespace pileDeChar { // interface dans un fichier Pile.h void empiler( char ) ; char depiler() ; bool estVide() ; }
7
Encapsulation: espace de nommage Exemple. Utilisation Un fichier Test-pile.cpp peut alors utiliser linterface : #include "pile.h" #include int main() { pileDeChar::empiler( x ) ; if (pileDeChar::depiler() != x) std::cerr << "impossible\n." ; } Rappel: le préfixe pileDeChar:: indique que empiler() et depiler() sont ceux du module pileDeChar.
8
Encapsulation: espace de nommage Exemple. Implémentation Limplé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 ;} }
9
Encapsulation: espace de nommage Exemple. Implémentation Il est possible de donner limplémentation dune fonction séparément (ici dans Pile.cpp), en préfixant le nom de la fonction par lidentificateur 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 ( ) {... } ;
10
Encapsulation: espace de nommage Exemple. Bon usage du 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 ny a pas dambiguïté. int main() { pileDeChar::empiler(a); using namespace pileDeChar; depiler(); return 0; }
11
Bon usage du using Inutile de mettre des using pour chacun des namespaces disponibles : l'ambiguïté revient. Un using peut-être local : Ne jamais utiliser de using dans un.h : tous les fichiers qui l'incluront seront pollués. // Quelque part { using namespace Util; // Util est accessible directement dans ce bloc }
12
Bon usage du using #include "MaLib1.h" #include "MaLib2.h" #include namespace util { class B { public : std::string afficher(); private: Tp1::A a; std::string tmp; }; } // --- namespace util std::string afficher() { using namespace std; string s; // traitement à faire return s; } On peut rajouter quelque chose dans un namespace déjà défini ailleurs. Ce using n'affecte que le corps de cette fonction.
13
Encapsulation: espace de nommage Koenig lookup Une fonctionnalité intéressante des espaces de nommage est le Koenig lookup : lors dun appel à une fonction le type des arguments permet parfois de lever lambiguï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 dajouter des données ou des méthodes).
14
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; }
15
Namespace et librairie standard librairie standard en C++ : dans le namespace std : Fonctions I/O ( console, fichiers,... ) Classes de base ( string, iterator,... ) Conteneurs ( vector, list,... ) Algorithmes standardisés ( tri, recherche, …) souvent la commande using namespace std; dans les fichiers.cpp.
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.