319 votes

Pourquoi les espaces de noms sans nom utilisé et quels sont leurs avantages ?

Je viens de rejoindre un nouveau projet de logiciel C++ et j’essaie de comprendre la conception. Le projet utilise fréquemment des espaces de noms sans nom. Par exemple, quelque chose comme cela peut se produire dans un fichier de définition de classe :

Quelles sont les considérations de conception qui pourraient causer d’utiliser un espace de noms sans nom ? Quels sont les avantages et les inconvénients ?

251voto

Johannes Schaub - litb Points 256113

(Dans la suite, le barré-à travers les choses sont des choses qui ne s'applique plus à C++11, mais ne s'appliquent à C++03. C++11 ne fait presque pas de différences plus (si il y en a, ils sont juste dans la langue de l'avocat différences dont je ne me souviens pas).).

Sans nom les espaces de noms sont un utilitaire pour faire un identificateur efficacement la traduction locale de l'unité. Ils se comportent comme si vous choisissez un nom unique par unité de traduction pour un espace de noms:

namespace unique { /* empty */ }
using namespace unique;
namespace unique { /* namespace body. stuff in here */ }

L'étape supplémentaire en utilisant le vide d'un corps est important, de sorte que vous pouvez déjà consulter dans l'espace de noms du corps à des identificateurs comme ::name qui sont définies dans l'espace de noms, depuis l'aide de la directive a déjà eu lieu.

Cela signifie que vous pouvez avoir gratuitement les fonctions appelées (par exemple) help qui peut exister dans plusieurs unités de traduction, et ils ne sera pas en conflit au moment de la liaison, car ils ont tous reçu un nom unique en raison de leur espace de noms unique, ils sont en. L'effet est presque identique à l'aide de l' static de mots clés utilisés dans laquelle vous pouvez mettre dans la déclaration des identificateurs. static utilisé de cette manière est déconseillée en C++, car sans nom les espaces de noms sont une alternative supérieure, pouvant même faire une conversion du type de l'unité locale.

namespace { int a1; }
static int a2;

Les deux as'sont la traduction locale de l'unité et ne sera pas en conflit au moment de la liaison. Mais la différence est que l' a1 en l'espace de noms anonymes seulement , se fait un nom unique. Il a toujours une liaison externe et peuvent être exportées dans la table des symboles du fichier de l'objet en cours de création. Cela devient important si vous voulez utiliser son adresse comme un argument de modèle:

template<int * ptr> struct sample { };

// OK - a1 has external linkage
sample<&a1> s1; 
// NOT OK - translation unit locality is done by giving a2 internal linkage. 
sample<&a2> s2; 

Paramètres du modèle a avoir une liaison externe dans ce cas, l'identifiant doit être placée dans un espace de noms anonymes.

Lire l'excellent article au comeau-informatique "Pourquoi est un sans nom d'espace de noms utilisé à la place de statique?.

119voto

Motti Points 32921

D'avoir quelque chose dans un espace de noms anonymes signifie qu'elle est locale à cette unité de traduction (.fichier cpp et tout ce qu'il contient) cela signifie que si un autre symbole avec le même nom est défini par ailleurs il n'y aura pas une violation de l' Une Définition de la Règle (ODR).

C'est la même chose que le C d'avoir une variable globale statique ou statique de la fonction, mais il peut être utilisé pour des définitions de classe (et devrait être utilisé plutôt que d' static en C++).

Tous les anonymes espaces de noms dans le même fichier sont traités comme le même espace de noms et tous les anonymes namcspaces dans les différents fichiers sont distincts. Un anonyme, un espace de noms est l'équivalent de:

namespace __unique_compiler_generated_identifer0x42 {
    ...
}
using namespace __unique_compiler_generated_identifer0x42;

14voto

Marc Mutz - mmutz Points 10367

L'exemple montre que les personnes dans le projet que vous avez rejoint ne comprends pas anonyme espaces de noms :)

namespace {
    const int SIZE_OF_ARRAY_X;
    const int SIZE_OF_ARRAY_Y;

Ces n'avez pas besoin d'être dans un espace de noms anonymes, depuis const objet déjà avoir une liaison statique et par conséquent ne peut pas en conflit avec les identifiants du même nom dans une autre unité de traduction.

    bool getState(userType*,otherUserType*);
}

Et c'est effectivement un pessimisation: getState() a une liaison externe. Généralement, il vaut mieux préférer une liaison statique, qui ne pollue pas la table des symboles. Il est préférable d'écrire

static bool getState(/*...*/);

ici. Je suis tombé dans le même piège (il y a libellé de la norme qui suggèrent que les fichiers statiques sont quelque peu obsolètes en faveur de l'anonymat des espaces de noms), mais le fait de travailler dans un grand projet C++ comme KDE, vous obtenez beaucoup de gens qui se tournent de votre tête la bonne façon de le faire à nouveau :)

12voto

Max Lybbert Points 11822

Un espace de noms anonyme rend le clos variables, les fonctions, les classes, etc disponibles uniquement à l’intérieur de ce fichier. Dans votre exemple c’est une façon d’éviter les variables globales. Il n’y a aucune différence de performance temps d’exécution ou de la compilation.

Il n’est pas tellement un avantage ou un inconvénient à part « que je veux cette variable, classe, fonction, etc. pour être public ou privé ? »

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X