Question

Je sais et je comprends que les variables globales et les nombres magiques sont des choses à éviter lors de la programmation, en particulier comme la quantité de code dans votre projet se développe. Je ne peux cependant pas penser à une bonne façon de s'y prendre pour éviter les deux.

que j'ai une variable prédéterminée représentant la largeur de l'écran, et la valeur est nécessaire dans plusieurs fichiers. Je pouvais faire ...

doSomethingWithValue(1920);

Mais c'est un nombre magique. Mais pour éviter cela, je ferais ...

const int SCREEN_WIDTH = 1920;

//In a later file...
extern const int SCREEN_WIDTH;
doSomethingWithValue(SCREEN_WIDTH);

Et maintenant, je suis en utilisant une variable globale. Quelle est la solution ici?

Était-ce utile?

La solution

Dans votre deuxième exemple, SCREEN_WIDTH est pas vraiment une variable 1 , il est constante nommée . Il n'y a rien de mal à l'utilisation constante du nom du tout.

En C, vous voudrez peut-être utiliser un ENUM si elle est une constante entière parce qu'un objet const est pas une constante. En C ++, l'utilisation d'un objet const comme vous avez dans la question initiale est préférable, car en C ++ un objet const est une constante.

1. Techniquement, oui, il est une « variable », mais ce nom n'est pas vraiment « correct », car il ne change jamais.

Autres conseils

Je recommande la définition de la constante dans un espace de noms dans un fichier d'en-tête. Ensuite, la portée est pas globale et vous n'avez pas besoin de redéfinir (même avec le mot-clé extern) à plusieurs endroits.

Pourquoi avez-vous besoin de coder en dur la largeur de l'écran en premier lieu? D'où est ce que ça vient? Dans la plupart des applications réelles, il vient d'une API du système, qui vous indique la résolution que vous êtes actuellement en cours d'exécution ou les résolutions du système est capable d'afficher.

Ensuite, vous prenez cette valeur et passe à chaque fois que cela est nécessaire.

En bref, sur cette ligne: doSomethingWithValue(SCREEN_WIDTH); que vous faites déjà. SCREEN_WIDTH pourrait être un mondial dans cet exemple particulier, mais il ne doit pas être, parce que la fonction n'est pas y accéder comme mondial. Vous passez la valeur à la fonction lors de l'exécution, de sorte que la fonction ne voit pas est une variable globale, il est juste un argument de fonction simple.

Un autre point important est qu'il n'y a généralement rien de mal avec immuable données globales.

constantes globales sont généralement bien. Le problème se produit lorsque vous avez mutable : état global des objets accessibles dans l'ensemble de l'application, et qui pourrait avoir une valeur différente en fonction de lorsque vous regardez. Cela rend difficile de raisonner sur, et provoque un certain nombre de problèmes.

Mais global constantes sont en sécurité. Prenons par exemple pi. Il est une constante mathématique, et il n'y a pas de mal à laisser voir toutes les fonctions que pi est 3.1415 ..... parce que ce qu'il , et il ne va pas changer.

si l'écran largeur est une constante codée en dur (comme dans votre exemple), il peut aussi être un monde sans causer des ravages. (Bien que pour des raisons évidentes, il ne devrait probablement pas être une constante dans la première place9

Le principal problème avec les variables globales est quand ils sont non-const. GLOBALS non change ne sont pas une préoccupation de près, comme vous le savez toujours leur valeur partout où ils sont utilisés.

Dans ce cas, une approche saine d'esprit est de créer un espace de noms de constantes et de mettre les valeurs constantes là, pour ne importe où de référence dans votre programme. Cela ressemble beaucoup à votre deuxième exemple.

Ils doivent définir quelque part. Pourquoi ne pas mettre les définit dans un fichier .h ou dans un fichier de construction?

Il est pas une variable, il est constant, ce qui est résolu au moment de la compilation.

Quoi qu'il en soit, si vous ne le faites pas comme un « flottant » constante, vous pouvez le mettre dans un espace de noms ou autre pour recueillir toutes les constantes de ce type ensemble. Dans certains cas, vous pouvez également envisager une ENUM à des constantes liées au groupe.

Mieux encore, si cela peut appliquer à votre situation, évitez d'utiliser une largeur d'écran fixe prédéterminée et utiliser les API correctes pour le récupérer lors de l'exécution.

Si un mondial est un must alors il est généralement une bonne idée de l'envelopper dans une fonction et utiliser la fonction pour obtenir la valeur.

Un autre poste qui pourrait aide

Alors que le monde dans votre deuxième cas est assez anodin, à moins que vous concevez cela pour quelque chose où vous êtes que la largeur de l'écran ne changera pas, j'utiliser quelque chose à obtenir la largeur de l'écran de façon dynamique (par exemple, GetSystemMetrics sur Windows, ou sur XDisplayWidth X).

Une façon d'éviter cela serait de mettre en place votre programme comme un objet et une propriété sur l'objet (my_prog.screen_width). Pour exécuter votre programme, ont main () instancier l'objet et appeler un -.> Méthode aller sur l'objet

Java fait cela. Beaucoup. idée demi-décent.

Suppléments pour l'expansion de votre programme:

  • Lorsque vous faites votre programme personnalisable un jour, vous pouvez l'avoir défini la propriété dans le constructeur au lieu de tout recompiler.
  • Lorsque vous voulez exécuter deux instances de votre programme à côté de l'autre dans le même processus, ils peuvent avoir des paramètres différents.

Il est pas une affaire énorme pour un unique programme rapide, cependant.

Il est important de reconnaître que même les constantes globales peuvent parfois causer des problèmes si elles doivent être changées à l'avenir. Dans certains cas, vous pouvez décider que vous êtes tout simplement pas allez les laisser changer, mais d'autres fois les choses peut-être pas si facile. Par exemple, votre programme peut contenir une image graphique qui est dimensionné pour correspondre à l'écran; ce qui se passe si elle doit être ajustée pour fonctionner sur un écran de taille différente? Le simple fait de changer la constante du nom résoudra pas nécessairement l'image graphique qui est intégré dans le programme. Et si elle doit être en mesure de décider à l'exécution que la taille d'écran à utiliser?

Il est impossible de faire face à toutes les éventualités imaginables, et il ne faut pas essayer trop dur pour protéger contre les choses qui ne sont tout simplement pas ça va arriver. Néanmoins, il faut être conscient de ce que les choses peuvent changer, de façon à éviter de se la boxe dans un coin.

Lors de la conception d'une classe, ayant une propriété virtuelle qui retourne en lecture seule une valeur immuable permettra des extensions futures de la classe pour renvoyer des valeurs différentes. L'utilisation d'une propriété plutôt qu'une constante peut avoir des conséquences sur les performances, mais dans certains cas, la flexibilité en vaudra la peine. Il est peut-être bien s'il y avait une façon de définir des constantes virtuelles, et je ne vois aucune raison, il ne serait pas théoriquement possible .net pour lui permettre, (y compris les valeurs constantes dans la table avec des pointeurs de méthode virtuelle), mais pour autant que Je sais que cela ne fonctionne pas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top