Comment créez-vous une classe statique en C ++? Je devrais être capable de faire quelque chose comme:
cout << "bit 5 is " << BitParser::getBitAt(buffer, 5) << endl;
En supposant que j'ai créé la BitParser
classe. À quoi BitParser
ressemblerait la définition de classe?
Réponses:
Si vous cherchez un moyen d'appliquer le mot clé "statique" à une classe, comme vous pouvez le faire en C # par exemple, vous ne pourrez pas le faire sans utiliser Managed C ++.
Mais l'apparence de votre exemple, il vous suffit de créer une méthode statique publique sur votre objet BitParser. Ainsi:
BitParser.h
BitParser.cpp
Vous pouvez utiliser ce code pour appeler la méthode de la même manière que votre exemple de code.
J'espère que cela pourra aider! À votre santé.
la source
private: BitParser() {}
Cela empêchera quiconque de créer des instances.BitParser() = delete;
transmettre correctement l'intention de supprimer le constructeur (et pas seulement de le cacherprivate
).Considérez la solution de Matt Price .
Ce que vous voulez est exprimé dans la sémantique C, pour mettre votre fonction (car il est une fonction) dans un espace de noms.
Modifier 2011-11-11
Il n'y a pas de "classe statique" en C ++. Le concept le plus proche serait une classe avec uniquement des méthodes statiques. Par exemple:
Mais vous devez vous rappeler que les "classes statiques" sont des hacks dans les langages de type Java (par exemple C #) qui ne peuvent pas avoir de fonctions non membres, donc ils doivent plutôt les déplacer à l'intérieur des classes en tant que méthodes statiques.
En C ++, ce que vous voulez vraiment, c'est une fonction non membre que vous déclarerez dans un espace de noms:
Pourquoi donc?
En C ++, l'espace de noms est plus puissant que les classes pour le modèle "Java static method", car:
Conclusion: ne copiez / collez pas le modèle Java / C # en C ++. En Java / C #, le modèle est obligatoire. Mais en C ++, c'est du mauvais style.
Modifier le 2010-06-10
Il y avait un argument en faveur de la méthode statique, car parfois, il faut utiliser une variable de membre privé statique.
Je suis en désaccord quelque peu, comme indiqué ci-dessous:
La solution "Membre Privé Statique"
Tout d'abord, myGlobal est appelé myGlobal car il s'agit toujours d'une variable privée globale. Un regard sur la source du RPC clarifiera que:
À première vue, le fait que la fonction gratuite barC ne puisse pas accéder à Foo :: myGlobal semble une bonne chose du point de vue de l'encapsulation ... C'est cool parce que quelqu'un qui regarde le HPP ne pourra pas (sauf s'il a recours au sabotage) accéder Foo :: myGlobal.
Mais si vous y regardez de près, vous constaterez que c'est une erreur colossale: non seulement votre variable privée doit toujours être déclarée dans le HPP (et donc, visible par le monde entier, bien qu'elle soit privée), mais vous devez déclarer dans le même HPP toutes les fonctions (comme dans TOUS) qui seront autorisées à y accéder !!!
Donc, utiliser un membre statique privé, c'est comme marcher dehors nu avec la liste de vos amants tatoués sur votre peau: Personne n'est autorisé à toucher, mais tout le monde peut y jeter un œil. Et le bonus: tout le monde peut avoir les noms des personnes autorisées à jouer avec vos amis.
private
en effet ... :-DLa solution "espaces de noms anonymes"
Les espaces de noms anonymes auront l'avantage de rendre les choses privées vraiment privées.
Tout d'abord, l'en-tête HPP
Juste pour être sûr que vous avez remarqué: il n'y a pas de déclaration inutile de barB ni de myGlobal. Ce qui signifie que personne ne lisant l'en-tête ne sait ce qui se cache derrière barA.
Ensuite, le RPC:
Comme vous pouvez le voir, comme la déclaration dite de "classe statique", fooA et fooB peuvent toujours accéder à myGlobal. Mais personne d'autre ne le peut. Et personne d'autre en dehors de ce CPP ne sait que fooB et myGlobal existent même!
Contrairement à la "classe statique" marchant sur le nu avec son carnet d'adresses tatoué sur la peau, l'espace de noms "anonyme" est entièrement habillé , ce qui semble bien mieux encapsulé AFAIK.
Est-ce que c'est vraiment important?
À moins que les utilisateurs de votre code ne soient des saboteurs (je vous laisse, comme exercice, trouver comment on peut accéder à la partie privée d'une classe publique en utilisant un hack sale non défini ...), qu'est-ce qui
private
se passeprivate
, même s'il est visible dans laprivate
section d'une classe déclarée dans un en-tête.Pourtant, si vous avez besoin d'ajouter une autre "fonction privée" avec accès au membre privé, vous devez toujours la déclarer à tout le monde en modifiant l'en-tête, ce qui est un paradoxe en ce qui me concerne: si je change la mise en œuvre de mon code (la partie CPP), puis l'interface (la partie HPP) ne doit PAS changer. Citant Leonidas: " C'est de l'ENCAPSULATION! "
Modifier le 2014-09-20
Quand les classes les méthodes statiques sont-elles réellement meilleures que les espaces de noms avec des fonctions non membres?
Lorsque vous devez regrouper des fonctions et alimenter ce groupe dans un modèle:
Parce que, si une classe peut être un paramètre de modèle, les espaces de noms ne le peuvent pas.
la source
#define private public
dans les en-têtes ... ^ _ ^ ...utilities
espace de noms. De cette façon, cette fonction peut être testée à l'unité, et n'a toujours pas d'accès spécial aux membres privés (car ils sont donnés comme paramètres lors de l'appel de fonction) ...namespace
volonté, n'aura-t-il pas accès à vos membresglobal
, bien que cachés? De toute évidence, ils devraient deviner, mais à moins que vous ne masquiez intentionnellement votre code, les noms de variables sont assez faciles à deviner.Vous pouvez également créer une fonction libre dans un espace de noms:
Dans BitParser.h
Dans BitParser.cpp
En général, ce serait la manière préférée d'écrire le code. Lorsqu'il n'y a pas besoin d'un objet, n'utilisez pas de classe.
la source
Les classes statiques sont simplement le compilateur qui vous tient à la main et vous empêche d'écrire des méthodes / variables d'instance.
Si vous écrivez simplement une classe normale sans aucune méthode / variable d'instance, c'est la même chose, et c'est ce que vous feriez en C ++
la source
static
200 fois serait une bonne chose.En C ++, vous souhaitez créer une fonction statique d'une classe (pas une classe statique).
Vous devriez alors être en mesure d'appeler la fonction en utilisant BitParser :: getBitAt () sans instancier un objet que je suppose être le résultat souhaité.
la source
Puis-je écrire quelque chose comme
static class
?Non , selon le projet d' annexe C 7.1.1 de la norme C ++ 11 N3337 :
Et comme
struct
,class
c'est aussi une déclaration de type.La même chose peut être déduite en parcourant l'arbre de syntaxe de l'annexe A.
Il est intéressant de noter que
static struct
c'était légal en C, mais n'a eu aucun effet: pourquoi et quand utiliser des structures statiques en programmation C?la source
Comme il a été noté ici, un meilleur moyen d'y parvenir en C ++ pourrait être d'utiliser des espaces de noms. Mais puisque personne n'a mentionné le
final
mot - clé ici, je poste à quoi ressemblerait un équivalent directstatic class
de C # en C ++ 11 ou version ultérieure:la source
Vous 'pouvez' avoir une classe statique en C ++, comme mentionné précédemment, une classe statique en est une qui n'en a aucun objet instanciée. En C ++, cela peut être obtenu en déclarant le constructeur / destructeur privé. Le résultat final est le même.
la source
En C ++ managé, la syntaxe de classe statique est: -
... Mieux vaut tard que jamais...
la source
Ceci est similaire à la façon de faire de C # en C ++
Dans C # file.cs, vous pouvez avoir une var privée dans une fonction publique. Dans un autre fichier, vous pouvez l'utiliser en appelant l'espace de noms avec la fonction comme dans:
Voici comment faire la même chose en C ++:
SharedModule.h
SharedModule.cpp
OtherFile.h
OtherFile.cpp
la source
Contrairement à d'autres langages de programmation managés, "classe statique" n'a AUCUNE signification en C ++. Vous pouvez utiliser la fonction membre statique.
la source
Un cas où les espaces de noms peuvent ne pas être aussi utiles pour atteindre des "classes statiques" est lors de l'utilisation de ces classes pour obtenir une composition sur l'héritage. Les espaces de noms ne peuvent pas être amis des classes et ne peuvent donc pas accéder aux membres privés d'une classe.
la source
Une (parmi les nombreuses) alternatives, mais la plus (à mon avis) élégante (par rapport à l'utilisation d'espaces de noms et de constructeurs privés pour émuler le comportement statique), la manière d'obtenir le comportement "classe qui ne peut pas être instanciée" en C ++ serait de déclarer une fonction virtuelle pure factice avec le
private
modificateur d'accès.Si vous utilisez C ++ 11, vous pouvez aller plus loin pour vous assurer que la classe n'est pas héritée (pour purement émuler le comportement d'une classe statique) en utilisant le
final
spécificateur dans la déclaration de classe pour empêcher les autres classes de l'hériter. .Aussi stupide et illogique que cela puisse paraître, C ++ 11 permet la déclaration d'une "fonction virtuelle pure qui ne peut pas être remplacée", que vous pouvez utiliser en même temps que déclarer la classe
final
pour implémenter purement et entièrement le comportement statique car cela entraîne la résultante classe ne doit pas être héritable et la fonction factice ne doit pas être remplacée en aucune façon.la source