Je comprends qu'une bibliothèque C ++ devrait utiliser un espace de noms pour éviter les collisions de noms, mais que je dois déjà: Ne cesse pas ces deux paramètres infère em> les mêmes informations véhiculées par un espace de noms. L'utilisation d'un espace de noms présente maintenant un troisième paramètre - le nom pleinement qualifié. Si la mise en œuvre de la bibliothèque change, il y a maintenant trois em> choses potentielles que j'ai besoin de changer. N'est-ce pas, par définition une augmentation du couplage entre le code de la bibliothèque et mon code? P> Par exemple, regardez Xerces-C: il définit une interface virtuelle pure appelée Comme le code évolue, il est peut-être nécessaire de laisser tomber des XERCES en faveur d'un analyseur différent. Je suis partiellement "protégé" de la modification de la mise en œuvre de la bibliothèque par l'interface pure-virtuelle (encore plus si j'utilise une usine pour construire mon analyseur), mais dès que je passerai de Xerces à autre chose, j'ai besoin de peigne à travers mon code et modifier tout mon Je l'ai rencontré récemment quand j'ai refoulé Un projet C ++ existant pour scinder certaines fonctionnalités utiles existantes dans une bibliothèque: p> en grande partie de l'ignorance (et partiellement hors de la paresse) à l'époque, la toutes les fonctionnalités de comme le contenu de Le client foo.cpp strong> p> mais le
#include code> L'en-tête correct (ou renvoyer les classes que j'ai l'intention d'utiliser) li>
analyseur Dans l'espace de noms
Xerces_cpp_namespace code>. Je peux utiliser l'interface code> parser code> dans mon code en incluant le fichier d'en-tête approprié, puis importer l'espace de noms
à l'aide de l'espace de noms xerces_cpp_namespace code> ou préfaborant les déclarations / définitions avec
xerces_cpp_namespace :: code>. p>
à l'aide de l'espace de noms xerces_cpp_namespace code> et
xerces_cpp_namespace :: parser code> code. p>
i utile.lib code> a été placé dans l'espace de noms global. p>
utile.lib code> a grandi (et plus de clients ont commencé à utiliser la fonctionnalité), il a été décidé de déplacer tout le code de
utile.lib Code> dans son propre espace de noms appelé
"utile" code>. p>
.cpp code> Les fichiers ont été faciles à réparer, il suffit d'ajouter un espace de noms utile code>; p>
.h code> fichiers étaient vraiment em> intensive de travail. Au lieu de polluer l'espace de noms global en mettant
à l'aide de l'espace de noms utile; code> dans les fichiers d'en-tête, j'ai enveloppé les déclarations avant existantes dans l'espace de noms: p>
namespace useful {
class Useful; // Forward Declaration
}
class Foo
{
public:
Foo(const useful::Useful& u);
...snip...
}
7 Réponses :
(a) interfaces / classes / fonctions de la bibliothèque p> blockQuote>
Pas plus que ce que vous avez déjà. Utilisation des composants CODE> NAMESPACE CODE> BIBLIBLE DE BIBLATION vous aide à la pollution des espaces de noms. P>
(b) les détails de la mise en œuvre déduits par l'espace de noms? p> blockQuote>
Pourquoi? Tout ce que vous devriez être compris est un en-tête
utile.h code>. La mise en œuvre doit être cachée (et réside dans le
utile.cpp code> et probablement dans un formulaire de bibliothèque dynamique). P>
Vous pouvez inclure sélectivement les classes que vous avez besoin de
utiles.h code> en utilisant
en utilisant utile :: utile code> déclarations. P>
Si vous avez plusieurs implémentations de votre bibliothèque "utile", n'est-ce pas tout aussi probable (sinon sous votre contrôle) qu'ils utiliseraient la même espace de noms, que ce soit l'espace de nom global em> ou l'espace de noms utile em> p>
Mettez un autre moyen, en utilisant un espace de noms nommé par rapport à l'espace de noms global n'a rien à voir avec la manière dont vous êtes "couplé" dans une bibliothèque / mise en œuvre. P>
Toute stratégie d'évolution de la bibliothèque cohérente devrait maintenir la même espace de noms pour l'API. La mise en œuvre pourrait utiliser différents espaces de noms masqués de vous et ceux-ci pourraient changer dans différentes implémentations. Je ne sais pas si c'est ce que vous entendez par «Détails de la mise en œuvre déduits par l'espace de noms». P>
Non, vous n'allez pas augmenter le couplage. Comme d'autres l'ont dit - je ne vois pas comment l'espace de noms d'espace fuit la mise en œuvre de la mise en œuvre
le consommateur peut choisir de faire p> mon vote est toujours pour la dernière - sa Le moins polluant p> le premier doit être fortement découragé (par équipe de tir) p> p>
Vraisemblablement pour le premier que vous avez prévu à l'aide de l'espace de noms utile; code>?
L'espace de noms n'a rien à voir avec le couplage. Le même couplement existe si vous l'appelez Pour faciliter le transfert, vous auriez pu écrire un en-tête code> code> (il y a un couple dans la STL, vous pouvez sûrement le trouver dans les bibliothèques) comme Toujours, couplage et espaces de noms ne sont que sans rapport. Une rose sentirait aussi douce par tout autre nom et vos classes sont aussi couplées dans n'importe quel autre espace de noms. P> utile :: Classe utile code> ou juste
Class utile code>. Maintenant, le fait que vous ayez besoin de faire tout ce que les travaux refactoring ne vous indiquent que dans quelle mesure votre code dépend de votre bibliothèque. P>
utilefwd.h code> que En avant, définissez l'interface de la bibliothèque (ou la mise en œuvre de classes ou tout ce dont vous avez besoin). Mais cela n'a rien à voir avec le couplage. P>
"Maintenant, le fait que vous ayez besoin de faire tout ce travail refactoring ne vous indique que dans quelle mesure votre code dépend de votre bibliothèque." C'est un très bon point. J'ai fait le code dans une bibliothèque afin que d'autres puissent en utiliser, mais mon code d'origine dépendait fortement de cette fonctionnalité.
Cela me semble que votre problème est principalement due à la manière dont vous êtes (AB) à l'aide des espaces de noms, pas en raison des espaces de noms eux-mêmes.
On dirait que vous lancez beaucoup de "trucs" minimalement liés dans un espace de noms, principalement (lorsque vous y êtes debout) parce qu'ils ont été développés par la même personne. Au moins IMO, un espace de noms doit refléter une organisation logique du code, pas seulement l'accident qu'un groupe d'utilitaires soit écrit par la même personne. P> li>
Un nom d'espace de noms doit généralement être assez long et descriptif pour éviter plus de possibilités de collision la plus éloignée d'une collision. Par exemple, j'inclus habituellement mon nom, date écrite et une brève description de la fonctionnalité de l'espace de noms. P> li>
La plupart des codes client n'ont pas besoin de (et ne devraient souvent pas) utiliser le vrai nom de l'espace de noms directement. Au lieu de cela, il devrait définir un alias d'espace de noms, et seul le nom d'alias doit être utilisé dans la plupart des codes. P> LI> ol>
Publier des points deux et trois ensemble, nous pouvons vous retrouver avec du code quelque chose comme ceci: p> Ceci supprime (ou du moins radicalement réduit) le couplage entre le code client et une implémentation particulière des classes de date / heure. Par exemple, si je voulais ré-implémenter les mêmes classes de date / heure, je pourrais les mettre dans un espace de noms différent et basculer entre l'un et l'autre simplement en modifiant l'alias et en rééquilibrant. P> En fait, j'ai utilisé cela parfois comme une sorte de mécanisme de polymorphisme de la compilée. Pour un exemple, j'ai écrit quelques versions de couple d'une petite classe "Affichage" qui affiche la sortie dans une liste de liste Windows et une autre qui affiche la sortie via iostreams. Le code utilise ensuite un alias quelque chose comme: p> le reste du code utilise simplement affichage :: Quel que soit le code>, donc aussi longtemps que les deux espaces de noms L'ensemble de l'interface, je peux utiliser l'une quelconque, sans changer le reste du code, et em> sans aucune surcharge d'exécution de l'utilisation d'un pointeur / référence à une classe de base avec des fonctions virtuelles pour les implémentations. < / p> p>
"comme une sorte de mécanisme de polymorphisme de temps d'exécution" i> - qui devrait être "compilé-time" i>?
@gf: Oups, oui. Merci. Je vais résoudre ça.
Dieu, je ne nomme définitivement pas mes espaces de noms avec mon nom de famille et ma date ... Nous avons quelques centaines de composants au travail, et le nom est généralement le nom du composant, pour les différencier :)
@Matthieu: Le point est simplement de trouver un modèle que vous pouvez suivre qui donne une assurance raisonnable que c'est unique. L'ensemble de ce que je préconise est qu'à propos de la seule fois que vous utilisez ce nom directement est comme la cible d'un alias.
Je comprends, mais chacun de votre client doit envelopper vos en-têtes avec l'alias ou redéfinir l'alias à chaque inclusion, c'est une peine. En outre, en tant que convention de dénomination, j'utilise l'espace de noms comme chemin de mon fichier >> #include "nom1 / nom2 / class.h" code> signifie
nom1 :: nom2 :: classe Code>, ce qui facilite l'identification d'un coup d'œil sur lequel module (sous-module ...) une classe appartient et quel en-tête l'apporte.
Eh bien, la vérité est qu'il n'ya aucun moyen d'éviter facilement l'enchevêtrement du code en C ++. L'utilisation de l'espace de noms global est la pire idée, cependant, car alors vous n'avez aucun moyen de choisir entre les implémentations. Vous vous retrouvez avec un objet au lieu de l'objet. Cela fonctionne bien dans la maison car vous pouvez éditer la source comme vous allez, mais si quelqu'un expédie du code comme celui-ci à un client, ils ne devraient pas s'attendre à ce qu'ils soient longtemps. P>
Une fois que vous avez utilisé l'instruction utilisée, vous pouvez également être global, mais cela peut être agréable dans les fichiers du CPP de l'utiliser. Donc, je dirais que vous devriez avoir tout dans un espace de noms, mais pour la maison, tout devrait être la même espace de noms. De cette façon, d'autres personnes peuvent utiliser votre code toujours sans catastrophe. P>
J'aimerais développer le deuxième paragraphe de David Rodrguez - Réponse de Dribesas (Upvoted):
Pour faciliter le transfert que vous auriez pu écrire un en-tête avancé (il y a un couple dans la STL, vous pouvez sûrement le trouver dans des bibliothèques) comme usefwd.h qu'environ uniquement défini l'interface de la bibliothèque (ou la mise en œuvre de classes ou tout ce dont vous avez besoin. ). Mais cela n'a rien à voir avec le couplage. P> BlockQuote>
Je pense que cela pointe sur le cœur de votre problème. Les espaces de noms sont un hareng rouge ici, vous avez été mordu en sous-estimant la nécessité de contenir des dépendances syntaxiques. P>
Je peux comprendre votre "paresse": il est em> pas juste à la surengroie ( > Enterprise em> helloworld.java), mais si vous gardez votre code à basse profil bas au début (ce qui n'est pas nécessairement faux) et que le code prouve un succès, le succès le traînera au-dessus de sa ligue. L'astuce est de sentir le bon moment pour passer à (ou employer dès le premier moment, le besoin apparaît) une technique qui se gronde à votre itch de manière compatible directe em>. p>
étincelant en avant Les déclarations sur un projet ne font que mendier pour une seconde et une série ultérieure. Vous n'avez pas besoin d'être un programmeur C ++ pour avoir lu l'avis "Ne pas renvoyer des flux standard, utilisez
code> à la place" (bien que cela ait été quelques années lorsque cela était pertinent. ; 1999? VC6 ERA, définitivement). Vous pouvez entendre beaucoup de cruches douloureuses des programmeurs qui n'ont pas pensé le conseil si vous faites une pause un peu. P> i peut em> comprendre l'envie de le garder à faible front, mais Vous devez admettre que
#include code> n'est plus une douleur que
de classe utile code> et échelles em>. Juste cette simple délégation vous épargnerait
n-1 code> modifications de la classe
utile code> à
classe utile :: utile code> p>
de Bien sûr, cela ne vous aiderait pas avec toutes les utilisations du code client. Aide facile: En fait, si vous utilisez une bibliothèque dans une application importante, vous devez envelopper les en-têtes transfrontaliers fournis avec la bibliothèque dans des en-têtes spécifiques à une application. L'importance de cela augmente avec la portée de la dépendance et de la volatilité de la bibliothèque. P>
src / libusef / usefwd.h em> p>
xxx pré> src / myapp / myapp-utilfwd.h em> p>
xxx pré> essentiellement, il s'agit de maintenir le code sec em >. Vous n'aimerez peut-être pas que Catchy TLAS, mais celui-ci décrit un principe de programmation véritablement de base. P> p>
"b) les détails de la mise en œuvre déduits par l'espace de noms" - pouvez-vous expliquer cela plus en détail? Je ne comprends pas ce que cela signifie.
Je me suis presque endormi avant d'avoir à la question, et je ne comprends toujours pas vraiment ce que vous demandez. Avez-vous considéré: utiliser utile :: utile;
C'est beaucoup de texte. Y a-t-il une version condensée que je pouvais lire?
@ *: Lisez l'avant-dernier paragraphe.
Pour moi c'est une histoire intéressante
+1: ignorer les ennemis. J'ai aimé lire votre message!
Et juste à titre de répondre à votre question, l'utilisation des espaces de noms n'a aucun impact sur le couplage. Vous devez I> utiliser des espaces de noms dans le code de la bibliothèque pour exactement la raison pour laquelle vous faites - pour obtenir votre nom de l'espace de noms global.
J'aime ce post et j'ai traversé exactement ce que vous me décrivez.
+1 pour style. J'aime des combinaisons improbables et poétique C ++ est exécuté que ce puits est une œuvre d'art. ;) (C'était long et je ne sais pas vraiment pourquoi je ne me suis pas enfui à la première vue du volume, mais c'était amusant)
Mais sérieusement, qu'est-ce que inféré i> est censé vouloir dire?
Je viens de modifier la question originale - j'espère que cela en fait un peu plus clair ce que j'essayais de demander.
Juste pour ce que ça vaut, ADL (Aka Koenig Lookup) peut introduire un couplage "inféré" à un espace de noms - c'est-à-dire à utiliser un nom d'un espace de noms peut conduire à un autre nom étant satisfait de cet espace de noms sans être spécifié pour le deuxième nom.
+1 à cause de la belle langue
Je vous suggère de considérer une méthode de versions dans votre code. Je ne sais pas comment je ferais ce guichet automatique.
-1 pour la "belle langue". Au cas où tout le monde l'avait manqué, il n'y a donc pas une aire de jeux écrivains ou un exercice de langue poétique. C'est un site de questions / réponses. Une bonne question n'est pas "agréable" ou "poétique", mais "claire" et "facilement compréhensible". Ce n'est pas le cas, car vous devez lire un demi-roman avant même d'arriver à la question. Et si ce n'est pas une raison suffisante pour écrire des questions concises et claires, que diriez-vous de celui-ci? Les gens sont moins enclins à lire i> votre question si cela prend une meilleure partie d'une heure. Ce qui signifie moins de réponses qualifiées.
@jalf et al: Si c'était un mauvais post à cause de la langue, ce n'est que parce que la communauté l'a dit. La communauté obtient ce que veut la communauté. Et je ne veux pas de sorte que c'est si rigide, si robotique et autonome que cela n'accepte que des questions réglementées. Étant donné que cette question a eu plus que le nombre habituel de prostitution et de points de vue, il me semble que je ne suis pas le seul à ressentir de cette façon.
Et si la communauté disant qu'ils ne sont pas universellement opposées à de tels postes ne risquent pas de reconsidérer les questions de rejet basées simplement sur la langue et l'élaboration, que diriez-vous de celui-ci? Très souvent, lorsqu'une affiche pose une question, il ne peut obtenir qu'une réponse appropriée à leurs besoins réels lorsque leur motivation i> pour essayer quelque chose d'une manière particulière est élaborée. Si nous disons que la règle est "Vous devez poser votre question, ne pas élaborer, ne dis pas bonjour et ne dis pas merci", alors de nombreuses questions posées ici ne recevront jamais la meilleure réponse possible.
@John: Non, c'est une mauvaise question parce qu'elle est formée de manière à ce que de nombreuses personnes qui seraient autrement en mesure de répondre ne le feraient pas. I> Une bonne question est une bonne question que les gens sont disposés lire. Personne ne dit "ne pas élaborer". Par tous moyens, fournissez tout le contexte correspondant. Je dis juste "Ne vous gaspillez pas les 2 000 premiers mots en train de rédiger un roman qui n'a rien à voir avec ce que vous voulez demander". Lorsque des affiches compétentes comme Neil, qui sont parmi les intervenants les plus dignes de confiance des questions C ++ , il ne peut pas trouver la question actuelle i>, il y a un problème.
@John: Personne n'a dit "Ne dis pas bonjour et ne dis pas merci". Personne n'a dit "ne pas élaborer". C'est un argument de la paille et encore plus une perte de temps que le roman de l'OP. Ce que je et d'autres disent, c'est "Si vous voulez de bonnes réponses, écrivez des questions aussi simples que possible pour les personnes de lire, de comprendre et de répondre". Écrire des œuvres de fiction lorsque votre paragraphe Intro vous donnera plus ou de meilleures réponses. Rendre votre question clair pour nous i>.
@jalf: "Personne n'a dit" Ne dites pas bonjour et ne dites pas Merci "En fait, ils ont fait: meta.stackexchange.com/questions/2950/...