Bonjour,,
Quel est l'intéret d'un code tel que :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 namespace bamg{ using namespace std; class R2 { public: double x, y; }
Bonjour,,
Quel est l'intéret d'un code tel que :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 namespace bamg{ using namespace std; class R2 { public: double x, y; }
Bonjour,
namespace <nom> { ... } : définit un espace de nom.
... ça permet de réduire la portée de ce qui est entre { } à l'espace de nom.
using namespace <nom>; indique que le code qui suit peut utilisé l'espace de nom <nom> sans y faire référence explicitement.
voir FAQ Namespace
Salut,
En gros un espace de noms ( namespace) est une sorte de "boite" qui te permet de séparer les différents éléments afin d'éviter les conflits de noms.
En effet, le nom de l'espace de noms intervient dans le noms complet de la fonction ou de la classe que tu déclares / définis. (on parle de "nom pleinement qualifié)
La directive using namespace te permet juste de "raccourcir" le nom (des fonctions, et des classes) à l'utilisation.
Ainsi, si tu as quelque chose qui correspond à
tu au final quatre fonctions nommées "foo" différentes grâce au fait qu'elles sont dans des espaces de noms différents:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 namespace Premier{ namespace Second{ namespace Troisieme{ void foo(); } void foo(); } void foo(); } void foo();
Bien sur, présenté sous cette forme, la directive using namespace n'aura strictement aucun intérêt car, si grâce à cette directive, tu peux éviter d'avoir à écrire à chaque fois Premier::, Premier::Second ou Premier::Second::Troisième (selon l'espace de noms que tu utilises dans ta directive), le fait d'appeler foo() (1) provoquera un conflit de noms avec Premier::foo, Premier::Second::foo ou Premier::Second::Troisieme::foo (en fonction de la directive, toujours)
- foo() (ligne 10)
- Premier::foo() (ligne 8)
- Premier::Second::foo (ligne 6)
- Premier::Second::Troisieme::foo (ligne 4)
Par contre, si les différentes fonctions foo étaient déclarées dans différents fichiers d'en-tête, sous la forme de
A.h
B.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 #ifndef A_H #define A_H void foo(); #endif
C.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 #ifndef B_H #define B_H namespace Premier{ void foo(); } #endif
D.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 #ifndef C_H #define C_H namespace Premier{ namespace Second{ void foo(); } } #endif
tu pourrais très bien utiliser la directive using namespace dans un code proche de
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 #ifndef D_H #define D_H namespace Premier{ namespace Second{ namespace Troisieme{ void foo(); } } } #endif
Du moins, tant que A.h n'est pas inclus en même temps qu'un autre fichier d'en-tête et que tu te limites à une seule directive.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 #include <C.h> using namespace Premier::Second::Troisieme; void bar(){ foo(); // fait appel à Premier::Second::Troisieme::foo(); }
Car, tu pourrais arriver à une situation proche deou de sa variante
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 #include <B.h> #inlcude <C.h> using namespace Premier; using namespace Premier::Second; void bar(){ foo(); // !!! appelle Premier::foo() ou Premier::Second::foo()??? }
Tout cela pour dire qu'il faut être particulièrement attentif lorsque l'on décide d'utiliser la directive using namespace et, surtout, qu'il est préférable de ne jamais l'utiliser dans un fichier d'en-tête (*.h) car, avec le jeu des inclusions en cascade, on n'a aucune idée de l'endroit où elle va agir au final.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 #include <B.h> #inlcude <C.h> #include <bar.h> using namespace Premier::Second; namespace Premier{ void bar(){ foo(); // !!! appelle Premier::foo() ou Premier::Second::foo()??? } }
Généralement, il est "de bon ton" de considérer que, si une équipe de développement a décidé de placer son projet dans des espaces de noms, c'est pour de bonnes raisons (le fait d'éviter les conflits de noms éventuels).
C'est la raison pour laquelle je suis (à titre personnel) globalement contre l'utilisation de la directive using namespace surtout en ce qui concerne l'espace de noms std car il n'est pas vraiment beaucoup plus long d'écrire quelque chose comme
que d'écrire la version utilisant la directive using namespace std;.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 void bar(){ std::string str; std::cout<</*...<<*/ std::endl; }
Par contre, il faut reconnaitre qu'utiliser de manière systématique du
à chaque fois qu'il faut faire appel à foo n'est vraiment pas efficace en terme de lecture (et il n'y a réellement qu'en terme de lecture que cela pose un problème
Code : Sélectionner tout - Visualiser dans une fenêtre à part Premier::Second::Troisieme::foo()).
Plutot que d'utiliser la directive using namespace je conseillerais alors d'utiliser un alias pour l'espace de noms: un nom "personnalisé" qui puisse représenter l'espace de noms qui nous intéresse.
Cela prendrait la forme de
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 #include <C.h> namespace PDT = Premier::Deuxieme::Troisieme; void bar{ PDT::foo(); // appelle Premier::Deuxieme::Troisieme::foo() }
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
Merci beaucoup pour cette réponse très détaillée et éclairante.
Partager