J'ai des fonctions qui peuvent être regroupées, mais n'appartiennent pas à un objet / entité et ne peuvent donc pas être traités comme des méthodes.
Ainsi, fondamentalement dans cette situation, je créerais un nouvel espace de noms et placez les définitions dans un fichier code> code>, l'implémentation dans le fichier Voir le code ci-dessous (probablement pas le meilleur exemple et pourrait être mieux fait avec une autre architecture de programme, mais je ne peux tout simplement pas penser à un meilleur échantillon ...) p> échantillon code ( échantillon code ( Si j'utilise des modèles, je dois mettre tout mon code dans le fichier code> (code>. Ok, mais comment dois-je dissimuler des détails de la mise en œuvre alors? p> Je veux masquer La seule approche que j'ai proposée était quelque chose comme: p> échantillon code ( CPP code>. Aussi (si nécessaire), je créerais un espace de noms anonyme dans ce fichier
cpp code> et mettre toutes les fonctions supplémentaires qui ne doivent pas être exposées / incluses à l'interface de mon espace de noms là-bas. P>
en-tête code>) em> p>
CPP code>) p> p> xxx pré>
réfractobjecte code> fonction de mon interface, mais je ne peux pas simplement supprimer sa déclaration (juste parce que j'ai tout mon code dans un (code> en-tête code > Fichier) ... P>
en-tête em>) em> P>
namespace algorithm {
// Is still exposed as a part of interface!
namespace impl {
template <typename T>
void RefractObject(T* object1) {
// Do something with that object
// (...)
}
}
template <typename T, typename Y>
void HandleCollision(T* object1, Y* object2) {
impl::RefractObject(object1);
// Another stuff
}
}
4 Réponses :
C'est une solution assez courante. Boost fait-le, et je le fais aussi bien, mais avec l'espace de noms code> code> à la place. Il suffit de faire une règle: "Ne regardez pas à l'intérieur File-Wise, je vous recommande de donner des détails sur leur propre fichier et le renseignez-vous dans un dossier de détail. C'est-à-dire que mon code serait semblable à: p> Il s'agit simplement d'une bonne pratique du code en général (gardez les choses fractionnées et réutilisables) et conserve le fichier de fichiers d'en-tête de Détails de la mise en œuvre. p> p> Détail CODE>!"
Vous ne pouvez pas masquer votre source de l'utilisateur à moins que vous ne le compilez en premier, ce qui est impossible avec des modèles. Donc, je suggère, dans un sens, que vous ne vous inquiétez pas. P>
doit aussi demander pourquoi réfracter ne peut pas être une méthode membre. P>
Membre de quoi? En outre, les fonctions libres sont préférées de toute façon. :)
Eh bien, j'y ai dit que ceci est juste pour un échantillon. Dans le cas de mon vrai projet algorithme code> inclut des algorithmes d'approximation et des algorithmes de recherche de chemin, de sorte qu'il est tout simplement impossible de leur faire
membres code> au sens de ce mot ...
Fonctions membres> Fonctions libres depuis l'invention d'IntelliSense.
Absolument pas. Les fonctions libres augmentent l'encapsulation et améliorent la réutilisation (juste pour nommer quelques choses) et sont, dans la conception moderne C ++, l'option préférée. Les fonctions doivent être nommées assez bien et suffisamment cohérentes pour ne pas avoir à compter sur IntelliSense. :)
Ils devraient être, mais ils ne sont pas, et le fait que IntelliSense existe et qu'un si grand outil prouve un tel outil. Heureux de réduire l'encapsulation et la réévalacité afin de pouvoir utiliser la fonction en question. La STL est particulièrement mauvaise pour vaporiser des fonctions libres dans STD, de sorte qu'il est impossible d'utiliser sans référence.
Construire une "classe statique" - au lieu de l'espace de noms, déclarez une classe avec le même nom. Rendre les opérateurs de constructeur, destructeur, de copie et d'affectation privés, puis faites chacune de vos fonctions autonomes une fonction de membre statique.
Un exemple d'exemple: P>
template<class T> class StringOperator { friend SomeOtherLibraryClass; // Let it use "Hidden()" private: StringOperator() {} ~StringOperator() {} StringOperator(const StringOperator&); StringOperator& operator=(const StringOperator&); static bool Hidden(const T& input) { // Hidden routine end-users shouldn't see... } public: static void YourFunction(T& parameter) { // Some public code.... } static T AnotherRoutine(const T* ptr) { // Some public code... } };
J'ai pensé à la même chose pendant un moment. En fin de compte, j'ai décidé d'utiliser des classes afin que le code soit plus portable, réutilisable et général. p>
Les deux seules raisons pour lesquelles vous utiliseriez l'espace de noms: p>
std :: for_ach code> vs boost :: for_ach code> li>
- Pour réduire le bruit visuel. Par exemple,
à l'aide d'un espace de noms Boost :: FileSystem code>, vous permettrait d'appeler sa fonction sans :: code>. li>.
ul>
Même pour ces deux cas, vous pouvez hériter de la classe qui a les méthodes ou renommer en initiatif ( my_own_filesystem_methods fs; code> et nous comme fs.mkdir () code> . De plus, . code> est plus court que :: code>. p>
Il y a d'autres avantages des espaces de noms tels que std :: cout << "hi" << endl; code> mais ce n'est pas très important. p>