Où déclarer/définition de la portée de classe constantes en C++?
Je suis curieux de connaître les avantages/inconvénients des différentes constante de la déclaration et la définition des options en C++. Pour le plus de temps, je viens de déclarant en haut de l'en-tête du fichier avant la définition de la classe:
//.h
const int MyConst = 10;
const string MyStrConst = "String";
class MyClass {
...
};
Tout cela pollue l'espace de noms global (qui je sais, c'est une mauvaise chose, mais n'ai jamais trouvé une liste de blanchisserie de raisons pour lesquelles il est mauvais), les constantes pourront encore être portée à l'individu d'unités de traduction, et donc les fichiers qui ne comprennent pas que cet en-tête n'ont pas accès à ces constantes. Mais vous pouvez obtenir des collisions de nom si d'autres classes de définir une constante du même nom, qui est sans doute pas une mauvaise chose car cela peut être une bonne indication d'une zone qui pourrait être remaniée.
Récemment, j'ai décidé qu'il serait mieux de déclarer la classe spécifique constantes à l'intérieur de la définition de la classe elle-même:
//.h
class MyClass {
public:
static const int MyConst = 10;
...
private:
static const string MyStrConst;
...
};
//.cpp
const string MyClass::MyStrConst = "String";
La visibilité de la constante serait ajusté en fonction de si la constante est utilisé uniquement en interne à la classe ou est nécessaire pour les autres objets qui utilisent la classe. C'est ce que je pense est la meilleure option à l'heure actuelle, principalement parce que vous pouvez garder interne des constantes de classe privée à la classe et les autres classes de l'aide du public constantes ne seraient plus en détail la référence à la source de la constante (par exemple Maclasse::MyConst). Il aussi de ne pas polluer l'espace de noms global. Bien qu'il ait, au détriment de l'nécessitant non partie intégrante de l'initialisation dans le fichier cpp.
J'ai aussi envisagé de déménager les constantes dans leur propre fichier d'en-tête et les emballer dans un espace de noms dans le cas de certains autres besoins de la classe des constantes, mais pas l'ensemble de définition de classe.
Simplement à la recherche d'avis et éventuellement d'autres options que je n'avais pas encore réfléchi.
Vous devez vous connecter pour publier un commentaire.
Votre demande de déclarer un non-intégrale constante comme un membre de classe statique "de l'avoir au détriment de l'nécessitant non partie intégrante de l'initialisation dans le fichier cpp" n'est pas exactement solide, pour ainsi dire. Elle nécessite une définition dans un fichier cpp, mais il n'est pas un "préjudice", c'est une question de votre intention. Espace de noms au niveau
const
objet en C++ a une liaison interne par défaut, ce qui signifie que dans votre variante originale de la déclarationest équivalent à
c'est à dire définir un indépendant
MyStrConst
objet dans chaque unité de traduction dans ce fichier d'en-tête est inclus. Êtes-vous au courant de cela? Était-ce votre intention ou non?En tout cas, si vous n'avez pas spécifiquement besoin d'un objet distinct dans chaque unité de traduction, de la déclaration de
MyStrConst
constante dans votre exemple n'est pas une bonne pratique. Normalement, vous auriez du mettre seulement une non-définition de la déclaration dans le fichier d'en-têteet de fournir une définition dans le fichier cpp
assurant que l'ensemble du programme utilise le même objet constant. En d'autres termes, quand il s'agit de non-constantes intégrales, une pratique courante consiste à les définir dans un fichier cpp. Donc, peu importe comment vous le déclarer (dans la classe ou à l'extérieur) vous sera normalement toujours avoir à traiter avec le "détriment" de l'avoir à la définir dans un fichier cpp. Bien sûr, comme je l'ai dit ci-dessus, avec les noms des constantes que vous pouvez vous en sortir avec ce que vous avez dans votre première variante, mais ce serait juste un exemple de "paresseux codage".
De toute façon, je ne pense pas qu'il y est une raison de plus de compliquer à l'excès la question: si la constante a un évident "attachement" à la classe, il doit être déclarée en tant que membre de la classe.
P. S. spécificateurs d'Accès (
public
,protected
,private
) ne contrôle pas visibilité de ce nom. Ils ne le contrôle de son accessibilité. Le nom reste visible en tout cas.De la Pollution de l'espace de noms global est mauvais parce que quelqu'un (par exemple, l'auteur d'une bibliothèque que vous utilisez), pourraient vouloir utiliser le nom
MyConst
pour un autre but. Cela peut conduire à de graves problèmes (bibliothèques qui ne peuvent pas être utilisés ensemble, etc.)Votre deuxième solution est clairement le meilleur si les constantes sont liés à une seule classe. Si ce n'est pas si facile (pensons à la physique ou les mathématiques constantes, sans être lié à une classe dans votre programme), l'espace de solution est mieux que ça. BTW: si vous devez être compatible aux anciens compilateurs C++, rappelez-vous certains d'entre eux ne peuvent pas utiliser intégrale d'initialisation dans un en-tête de fichier, vous devez l'initialiser dans le fichier C++ ou utiliser l'ancien
enum
truc dans ce cas.Je pense qu'il n'y a pas de meilleures options pour les constantes - à moins peut pas penser l'un à l'instant...
De polluer l'espace de noms global devrait être de soi mauvaise. Si j'inclus un fichier d'en-tête, je ne veux pas de rencontre ou de débogage nom de collisions avec des constantes déclarées dans l'en-tête. Ces types d'erreurs sont vraiment frustrant et parfois difficile à diagnostiquer. Par exemple, une fois, j'ai eu de lien à l'encontre d'un projet qui avait cette définie dans l'en-tête:
Si votre constantes de l'espace de noms de la pollution, c'est l'espace de noms des déchets nucléaires. La manifestation de cet été une série de très étrange erreurs du compilateur se plaindre de manque le savoir de la fonction, mais seulement lors de la liaison à l'encontre de la bibliothèque. Finalement nous avons renommé la lecture fonctions à autre chose, ce qui n'est pas difficile, mais doit être inutile.
Votre deuxième solution est très raisonnable, car il met la variable dans la portée. Il n'y a pas de raison que cela doit être associé à une classe, et si j'ai besoin de partager des constantes parmi les classes je vais déclarer des constantes dans leur propre espace de noms et le fichier d'en-tête. Ce n'est pas idéal pour la compilation, mais parfois c'est nécessaire.
J'ai aussi vu des gens mettre des constantes dans leur propre classe, qui peut être mis en œuvre comme un singleton. Cela me semble de travail sans récompense, la langue vous offre des installations pour déclarer des constantes.
Vous pouvez les déclarer en tant que variables globales dans le fichier c++, tant qu'ils ne sont pas référencés dans l'en-tête. Ensuite, ils sont privés de la classe et de ne pas polluer l'espace de noms global.
static
ou un anonyme, un espace de noms dans ce cas, si vous ne le faites pas, dans certaines implémentations de vous polluer l'espace de noms global utilisé par l'éditeur de liens et d'obtenir le nom d'affrontements sur le lien...Personnellement, j'utilise votre deuxième approche; je l'ai utilisé pendant des années, et il fonctionne bien pour moi.
D'une visibilité point, j'aurais tendance à rendre le privé fichier de constantes niveau statique en tant que personne en dehors de la mise en œuvre de fichier a besoin de savoir qu'ils existent; cela permet d'éviter la réaction en chaîne recompile si vous avez besoin de changer leurs noms ou d'en ajouter de nouveaux, comme leur nom l'étendue est la même que leur portée d'utilisation...
Si une seule classe va utiliser ces constantes, de les déclarer comme
static const
à l'intérieur du corps de classe. Si un groupe de classes associées allons utiliser les constantes, les déclarer à l'intérieur d'un class/struct qui ne contient que des constantes et l'utilité des méthodes ou à l'intérieur d'un espace de nom dédié. Par exemple,Si elles sont constantes utilisées par l'ensemble de l'application (ou une part substantielle de morceaux de celui-ci), les déclarer à l'intérieur d'un espace de noms dans un en-tête qui est (implicitement ou explicitement) inclus partout.
ne pas polluer l'espace de noms global, de polluer local.
Mais en pratique...
Pint
constante, et pourquoi neBar()
retour375
?