|
auteurs : LFE, Aurélien Regat-Barrel, JolyLoic |
Un namespace, ou espace de nom (parfois aussi espace de nommage, voire référentiel lexical) est une zone de déclaration d'identificateurs permettant au compilateur de résoudre les conflits de noms.
Si, par exemple, 2 développeurs définissent des fonctions avec le même nom, il y aura un conflit lors de l'utilisation de ces fonctions dans un programme. Les espaces de nommage permettent de résoudre ce problème en ajoutant un niveau supplémentaire aux identificateurs.
namespace a
{
void toto ()
{
}
}
namespace b
{
void toto ()
{
}
}
a:: toto ();
b:: toto ();
|
Les namespaces offrent une alternative élégante à diverses techniques pré-namespace telles que le préfixage des noms ou l'utilisation de préprocesseur :
void mylib_fonction1 ();
void mylib_fonction2 ();
|
L'exemple précédent peut s'écrire ainsi grâce aux namespaces :
namespace mylib
{
void fonction1 ();
void fonction2 ();
}
|
|
|
auteur : Aurélien Regat-Barrel |
Un namespace anonyme est un espace de nom... sans nom.
Un namespace anonyme a la particularité de n'être visible que par l'unité de compilation dans laquelle il se trouve (c'est à dire le fichier compilable). Son utilité est de permettre la déclaration d'une variable/fonction/type dont la portée doit être celle du fichier.
Parce qu'un namespace traduit mieux la notion de portée restreinte à un fichier, il est recommandé de privilégier son usage en C++ par rapport à celui du mot-clé static utilisé dans le même but mais en C.
|
|
auteurs : LFE, Luc Hermitte, Aurélien Regat-Barrel |
Si vous avez déclaré une classe ou des fonctions dans un espace de nom :
exemple.h |
namespace ns
{
class Test
{
public :
void F1 ();
void F2 ();
} ;
void Fonction1 ();
void Fonction2 ();
}
|
Il suffit de procéder de la même manière pour les implémenter, ou bien de préfixer par le nom du namespace :
exemple.cpp |
namespace ns
{
void Test:: F1 ()
{
}
void Fonction1 ()
{
}
}
void ns:: Test:: F2 ()
{
}
void ns:: Fonction2 ()
{
}
|
|
|
auteurs : Anomaly, Luc Hermitte, Aurélien Regat-Barrel |
Toute la bibliothèque standard C++ est définie dans son propre espace de nom, le namespace std. Ainsi, il faut systématiquement utiliser le préfixe
std:: devant tous les éléments qui en sont issus.
# include <iostream>
int main ()
std:: cout < < " cout " < < std:: endl;
}
|
Pour alléger l'écriture, on utilise l'expression using namespace std; ce qui permet de s'affranchir de l'obligation de préfixer par std::. Le code précédent peut alors s'écrire ainsi :
# include <iostream>
using namespace std;
int main ()
{
cout < < " coucou " < < endl;
}
|
Il est conseillé de limiter l'utilisation de using namespace car cela fait tout simplement perdre l'utilité des namespaces. En particulier, son usage est à proscrire dans les fichiers d'en-tête, ainsi que dans les cas où il génère des conflits avec d'autres namespaces. On peut pour cela restreindre la portée de la clause using à un bloc en particulier :
# include <iostream>
void affiche_coucou ()
{
using namespace std;
cout < < " coucou " < < endl;
}
int main ()
{
affiche_coucou ();
std:: cout < < " coucou " < < std:: endl;
}
|
Autre possibilité : importer un symbole du namespace et non le namespace tout entier :
# include <iostream>
using std:: cout;
using std:: endl;
int main ()
{
cout < < " coucou " < < endl;
}
|
|
|
auteur : JolyLoic |
Utiliser using namespace xxx; indique au compilateur qu'il a le droit, quand il voit un nom dans le reste de la portée courante,
de le rechercher dans l'espace de nom xxx, ce qui peut alléger le code, en permettant d'écrire :
using namespace std;
cout < < hex < < 42 < < endl;
|
Au lieu de
std:: cout < < std:: hex < < 42 < < std:: endl;
|
Par contre, cette écriture est à proscrire dans des fichiers d'en-tête, du moins à portée de fichier.
En effet, le but des espaces de nom est de permettre d'éviter des collisions de nom entre deux objets qui auraient le même nom,
mais provenant de deux sources différentes (et donc classés dans deux espaces de nom différents).
L'utilisation de using est un raccourci, mais il n'est possible que si on sait qu'il n'y a pas de conflits.
Si ce n'est pas le cas, il faut obligatoirement utiliser le nom qualifié des objets.
Or, dans le cadre d'un fichier d'en-tête, on ne peut pas savoir dans quels contextes ce fichier sera utilisé.
Et comme il n'existe pas de commande qu'on puisse insérer pour dire d'arrêter d'utiliser un using, on risque si on utilise
cette écriture dans un fichier d'en-tête de provoquer un conflit chez un de ses clients, qui n'aura aucun recours pour le corriger.
|
Consultez les autres F.A.Q's
Les sources présentées sur cette page sont libres de droits
et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation
constitue une œuvre intellectuelle protégée par les droits d'auteur.
Copyright © 2008 Developpez LLC.
Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne
peut être faite de ce site ni de l'ensemble de son contenu : textes, documents
et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez
selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.