314 votes

Namespace + fonctions par rapport aux méthodes statiques sur une classe

Disons que j’ai, ou je vais écrire, un ensemble de fonctions connexes. Disons qu’ils sont liées aux mathématiques. Sur le plan organisationnel, devrait I:

  1. Écrire ces fonctions et les mettre dans mon espace de noms et se réfèrent à eux par l’intermédiaire
  2. Créez une classe appelée et rendre ces méthodes statiques et se référer à la même

Pourquoi devrais-je choisir un sur l’autre comme un moyen d’organiser mon logiciel ?

260voto

paercebal Points 38526

Par défaut, l'utilisation des espaces de fonctions.

Les Classes sont à construire des objets, de ne pas remplacer les espaces de noms.

Dans le code Orienté Objet

Scott Meyers écrit tout un Article pour son Effective C++ livre sur ce sujet, "Préférer la non-membre non-amis fonctions de fonctions de membre". J'ai trouvé un site de référence à ce principe dans un article de Herb Sutter: http://www.gotw.ca/gotw/084.htm

La chose importante à savoir, c'est que: Dans les fonctions C++ dans le même espace de noms que d'une classe appartiennent à la catégorie de l'interface. (parce que l'ADL sera à la recherche de ces fonctions lors de la résolution des appels de fonction)

des espaces de fonctions, à moins que déclaré "ami" n'ont pas accès à la classe des' internes, alors que les méthodes statiques ont.

Cela signifie, par exemple, lors de l'entretien de votre classe, si vous avez besoin de changer votre classe interne, vous aurez besoin de recherche pour des effets secondaires dans l'ensemble de ses méthodes, y compris la statique.

Extension Je

Ajout de code pour la classe de l'interface.

En C#, vous pouvez ajouter des méthodes à une classe, même si vous n'avez pas accès à elle. Mais en C++, c'est impossible.

Mais, toujours en C++, vous pouvez toujours ajouter un espace de noms de fonction, même à une classe quelqu'un a écrit pour vous.

Voir de l'autre côté, ce qui est important lors de la conception de votre code, car en mettant vos fonctions dans un espace de noms, vous autoriser vos utilisateurs afin d'augmenter ou de compléter la classe de l'interface.

Extension II

Un effet secondaire du point précédent, il est impossible de déclarer des méthodes statiques dans plusieurs en-têtes. Toutes les méthodes doivent être déclarées dans la même classe.

Pour les espaces de noms, des fonctions à partir du même espace de noms peut être déclaré en plusieurs en-têtes (la quasi-norme de la fonction d'échange est le meilleur exemple).

Extension III

La base cooless d'un espace de noms est que, dans certains code, vous pouvez éviter de le mentionner, si vous utilisez le mot-clé "aide":

#include <string>
#include <vector>

// Etc.
{
   using namespace std ;
   // Now, everything from std is accessible without qualification
   string s ; // Ok
   vector v ; // Ok
}

string ss ; // COMPILATION ERROR
vector vv ; // COMPILATION ERROR

Et vous pouvez même limiter la "pollution" à une seule classe:

#include <string>
#include <vector>

{
   using std::string ;
   string s ; // Ok
   vector v ; // COMPILATION ERROR
}

string ss ; // COMPILATION ERROR
vector vv ; // COMPILATION ERROR

Ce "modèle" est obligatoire pour une bonne utilisation de la quasi-standard swap idiome.

Et c'est impossible à faire avec des méthodes statiques dans les classes.

Donc, C++ espaces ont leur propre sémantique.

Mais il va plus loin, comme vous pouvez le combiner des espaces de noms dans une manière similaire à l'héritage.

Par exemple, si vous disposez d'un espace de noms avec une fonction AAA, un espace de noms en B avec une fonction BBB, vous pouvez déclarer un espace de C, et apporter AAA et BBB dans cet espace de noms avec le mot-clé en utilisant.

Conclusion

Les espaces de noms sont pour les espaces de noms. Les Classes sont des classes.

C++ a été conçu de sorte que chaque concept est différent, et est utilisé différemment, dans différents cas, comme une solution à des problèmes différents.

N'utilisez pas de classes lorsque vous avez besoin d'espaces de noms.

Et dans votre cas, vous avez besoin d'espaces de noms.

59voto

Dan Tao Points 60518

Il y a beaucoup de gens qui sont en désaccord avec moi, mais c'est la façon dont je vois les choses:

Une classe est essentiellement une définition d'un certain type d'objet. Méthodes statiques devraient définir les opérations qui sont intimement liés à cette définition de l'objet.

Si vous allez juste pour avoir un ensemble de fonctions qui ne sont pas associés à un objet sous-jacent ou la définition d'un type d'objet, je dirais aller avec un espace de noms. Juste pour moi, sur le plan conceptuel, c'est beaucoup plus raisonnable.

Par exemple, dans votre cas, demandez-vous, "qu'est Ce qu'un MyMath?" Si MyMath ne permet pas de définir un type d'objet, alors je dirais: n'en faites pas une classe.

Mais comme je l'ai dit, je sais qu'il ya beaucoup de gens qui (même avec véhémence) sont en désaccord avec moi sur ce point (en particulier, Java et C# développeurs).

18voto

Shog9 Points 82052
  • Si vous avez besoin de données statiques, utiliser des méthodes statiques.
  • Si ils sont modèle de fonctions et que vous souhaitez être en mesure de spécifier un ensemble de paramètres de modèle pour toutes les fonctions de l'ensemble, puis utiliser des méthodes statiques dans une classe de modèle.

Sinon, utilisez des espaces de fonctions.


En réponse aux commentaires: oui, les méthodes statiques et les données statiques ont tendance à être sur-utilisé. C'est pourquoi j'ai proposé que deux, liés à des scénarios où je pense qu'ils peuvent être utiles. Dans le cas des OP des exemples spécifiques dans un ensemble de routines mathématiques), s'il voulait avoir la possibilité de spécifier des paramètres à - dire, un type de données et la précision de sortie - qui serait appliquée à toutes les routines, il pourrait faire quelque chose comme:

template<typename T, int decimalPlaces>
class MyMath
{
   // routines operate on datatype T, preserving at least decimalPlaces precision
};

// math routines for manufacturing calculations
typedef MyMath<double, 4> CAMMath;
// math routines for on-screen displays
typedef MyMath<float, 2> PreviewMath;

Si vous n'en avez pas besoin, puis par tous les moyens d' utiliser un espace de noms.

12voto

coppro Points 10692

Vous devez utiliser un espace de noms, parce que d'un espace de noms a de nombreux avantages par rapport à une classe:

  • Vous n'avez pas à définir tout dans le même en-tête
  • Vous n'avez pas besoin d'exposer toutes vos mise en œuvre dans l'en-tête
  • Vous ne pouvez pas using d'un membre de la classe; vous pouvez l' using d'un espace de noms membre
  • Vous ne pouvez pas using class, bien qu' using namespace n'est pas souvent une bonne idée
  • À l'aide d'une classe implique qu'il y a un objet à être créé quand il n'y a vraiment aucun

Les membres statiques sont, à mon avis, très très galvaudé. Ils ne sont pas une réelle nécessité dans la plupart des cas. Les membres statiques fonctions sont probablement mieux comme fichier-champ d'application les fonctions et les données membres statiques sont juste des objets globaux avec une meilleure réputation imméritée.

4voto

Motti Points 32921

J’aurais préféré des espaces de noms, de cette façon vous pouvez avoir des données privées dans un espace de noms anonyme dans le fichier de mise en œuvre (donc il ne doit pas apparaître dans l’en-tête du tout par opposition à membres). Un autre avantage est qu’en votre espace de noms les clients des méthodes peuvent opter hors spécification``

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