Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

Vous n'avez pas encore de compte Developpez.com ? L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Developpez.com

C++

Choisissez la catégorie, puis la rubrique :

logo
Sommaire > Les namespaces
        Qu'est-ce qu'un namespace ?
        Qu'est-ce qu'un namespace anonyme ?
        Comment définir l'implémentation d'une classe / fonction déclarée dans un namespace ?
        A quoi sert 'using namespace std;' ?
        Quand utiliser / ne pas utiliser using namespace ?



Qu'est-ce qu'un namespace ?
Mise à jour le 22/11/2004[haut]
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() // première fonction toto
    {
    }
}
namespace b
{
    void toto() // seconde fonction toto()
    {
    }
}
a::toto(); // appelle la première
b::toto(); // appelle la seconde
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();
}

Qu'est-ce qu'un namespace anonyme ?
Créé le 22/11/2004[haut]
auteur : Aurélien Regat-Barrel
Un namespace anonyme est un espace de nom... sans nom.
namespace
{
    int a; // variable déclarée dans un namespace anonyme
}
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.


Comment définir l'implémentation d'une classe / fonction déclarée dans un namespace ?
Mise à jour le 22/11/2004[haut]
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()
    {
    }
}

// autre possibilité

void ns::Test::F2()
{
}

void ns::Fonction2()
{
}

A quoi sert "using namespace std;" ?
Mise à jour le 22/11/2004[haut]
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;
    // dans tout le corps de la fonction préfixer par std:: est facultatif

    cout << "coucou" << endl;
}

int main()
{
    // ici il est obligatoire de préfixer par std::
    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()
{
    // si on veut utiliser cin par exemple, il faudra écrire std::cin
    cout << "coucou" << endl;
}
Pour plus d'informations, lire Qu'est-ce qu'un namespace ?.


Quand utiliser / ne pas utiliser using namespace ?
Créé le 03/02/2007[haut]
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;
Pour plus de détails, voir A quoi sert 'using namespace std;' ?.

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.


Valid XHTML 1.0 TransitionalValid CSS!

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.

Contacter le responsable de la rubrique C++

Partenaire : Hébergement Web