Pourquoi et comment dois-je utiliser des espaces de noms en C++?
Je n'ai jamais utilisé les espaces de noms pour mon code avant. (Autres que pour l'utilisation des fonctions STL)
- Autres que pour éviter les conflits de nom, est-il une autre raison pour utiliser des espaces de noms?
- Dois-je joindre les deux déclarations et les définitions dans l'espace de noms portée?
Vous devez vous connecter pour publier un commentaire.
Ici est une bonne raison (en dehors de l'évidente que vous avez déclaré).
Depuis l'espace de noms peuvent être discontinus et la propagation à travers les unités de traduction, ils peuvent aussi être utilisés pour séparer l'interface à partir de détails de mise en œuvre.
Définitions de noms dans un espace de noms peut être fournie soit dans le même espace ou dans l'un des englobant des espaces de noms (avec des noms pleinement qualifiés).
Une autre raison qui est souvent négligé, c'est que simplement en changeant une seule ligne de code pour sélectionner l'un des espaces de noms sur un autre, vous pouvez sélectionner un autre ensemble de fonctions/variables/types/constantes - comme une autre version d'un protocole, ou single-threaded versus multi-thread de support, support de l'OS pour la plate-forme de X ou de Y - compiler et exécuter. Le même effet peut être obtenu en incluant un en-tête avec les différentes déclarations, ou avec
#defines
et#ifdefs
, mais qui manque cruellement de touche l'ensemble de l'unité de traduction et si reliant les différentes versions, vous pouvez obtenir un comportement indéterminé. Avec des espaces de noms, vous pouvez effectuer des sélections via l'aide de noms qui s'appliquent seulement à l'intérieur de l'actif de l'espace de noms, ou de le faire par l'intermédiaire d'un espace de noms d'alias de sorte qu'ils ne s'appliquent que lorsque que l'alias est utilisé, mais en fait ils sont résolus à différents symboles de l'éditeur de liens, donc peut être combiné sans comportement indéfini. Cela peut être utilisé dans une manière semblable au modèle des politiques, mais l'effet est plus implicite, automatique et généralisée - un langage très puissant fonctionnalité.Mise à JOUR: face à l'marcv81 commentaire...
"de l'interface + implémentations" est conceptuellement ce que le choix d'un espace de noms d'alias ci-dessus est en train de faire, mais si vous voulez dire spécifiquement runtime polymorphisme et virtuel expédition:
la résultante de la bibliothèque ou de l'exécutable n'a pas besoin de contenir toutes les implémentations et constamment des appels directs à celui choisi lors de l'exécution
comme une mise en œuvre est incorporée, le compilateur peut utiliser une myriade d'optimisations, y compris l'in-lining, l'élimination du code mort, les constantes et les différences entre les "les implémentations" peut être utilisée, par exemple, les tailles de tableaux permettant l'automatisation de l'allocation de mémoire au lieu d'un ralentissement de la dynamique de l'allocation
différents espaces de noms à l'appui de la même sémantique de l'utilisation de la, mais ne sont pas liés à soutenir le même ensemble de signatures de fonction comme c'est le cas pour virtual expédition
avec des espaces de noms, vous pouvez fournir personnalisé non-membre des fonctions et des modèles: c'est impossible avec virtual expédition (et non des fonctions de membre d'aide avec le symétrique de surcharge d'opérateur - par exemple en aidant
22 + my_type
ainsi quemy_type + 22
)différents espaces de nom permettent de spécifier les différents types de être utilisés à certaines fins (par exemple, une fonction de hachage peut retourner une valeur 32 bits dans un espace de noms, mais une version 64 bits de valeur dans un autre), mais une interface virtuelle doit avoir fédérateur types statiques, ce qui signifie maladroit et de la haute-frais d'indirection comme
boost::any
ouboost::variant
ou un pire des cas, la sélection où les bits d'ordre élevé sont parfois dénuées de sensvirtuel envoi implique souvent des compromis entre la graisse interfaces et maladroit d'erreur de manipulation: avec des espaces de noms, il y a la option tout simplement de ne pas fournir des fonctionnalités dans des espaces de noms où il n'a pas de sens, donnant un moment de la compilation de l'application du client nécessaires effort de portage
auto foo = bar();
. Il peut compliquer le test, mais vous pouvez faire des choses commevoid test1() { using ns1; TEST_EQ(x, y()); }
- idem pourtest2
/ns2
- et exécuter les deux en un seul fichier exécutable. Parfois, l'aide d'une macro pour générer des fonctions de test avec différentsusing nsN;
permettrait de simplifier les choses, mais l'écriture de long macros devient laid. En déplaçant le test (plus précisément le corps de la fonction) dans un fichier de support que de multiplier inclus est une autre option. (De tels tests est souvent impossible pour#ifdef
ed code où le même symbole ou la fonction prend sur des définitions différentes).Il peut vous aider pour une meilleure compréhension.
par exemple:
Vous pouvez aussi penser à elle en tant que module dans votre système.
Il peut également être utile pour la rédaction de la documentation (par exemple: vous pouvez facilement le document d'espace de noms de l'entité dans doxygen)
Ne sont pas les collisions de nom de la raison suffisante? ADL subtilités, surtout avec la surcharge de l'opérateur, en sont un autre.
C'est le moyen le plus facile. Vous pouvez également les noms de préfixes avec l'espace de noms, par exemple my_namespace::nom, lors de la définition d'.
Vous pouvez penser à des espaces de logique unités séparées pour votre application, et de la logique signifie ici que supposons que nous avons deux classes différentes, la mise de ces deux classes, chacune dans un fichier, mais quand vous remarquez que ces classes de partager quelque chose de suffisant pour être classé dans une catégorie, c'est une bonne raison pour utiliser des espaces de noms.