91 votes

Définir une constante globale en C ++

Je veux définir une constante en C++ pour être visible dans plusieurs fichiers source. Je peux l'image de l'une des manières suivantes pour définir dans un fichier d'en-tête:

  1. #define GLOBAL_CONST_VAR 0xFF
  2. int GLOBAL_CONST_VAR = 0xFF;
  3. Une fonction returing la valeur (par exemple, int get_GLOBAL_CONST_VAR())
  4. enum { GLOBAL_CONST_VAR = 0xFF; }
  5. const int GLOBAL_CONST_VAR = 0xFF;
  6. extern const int GLOBAL_CONST_VAR; et dans un fichier source const int GLOBAL_CONST_VAR = 0xFF;

Option (1) - n'est certainement pas l'option que vous souhaitez utiliser

L'Option (2) - la définition de l'instance de la variable dans chaque fichier objet en utilisant le fichier d'en-tête

Option (3) - IMO est plus de mise à mort dans la plupart des cas

Option (4) - dans de nombreux cas, peut-être pas bon puisque enum n'a pas de type de béton (C++0X ajout de la possibilité de définir le type)

Ainsi, dans la plupart des cas, j'ai besoin de choisir entre (5) et (6). Mes questions:

  1. Que préférez-vous (5) ou (6)?
  2. Pourquoi (5) est ok, alors que (2) ne l'est pas?

75voto

Nikolai N Fetissov Points 52093

Sans aucun doute, choisissez l'option 5 - elle est sécurisée au niveau du type et permet au compilateur d'optimiser (ne prenez pas l'adresse de cette variable :) De plus, si l'en-tête est dans l'en-tête - collez-le dans un espace de noms pour éviter de polluer la portée globale:

 // header.hpp
namespace constants
{
    const int GLOBAL_CONST_VAR = 0xFF;
    // ... other related constants

} // namespace constants

// source.cpp - use it
#include <header.hpp>
int value = constants::GLOBAL_CONST_VAR;
 

36voto

Blindy Points 26706

(5) dit exactement ce que vous voulez dire. De plus, cela permet au compilateur de l’optimiser la plupart du temps. (6) d’autre part, ne laissera jamais le compilateur l’optimiser parce que le compilateur ne sait pas si vous le changerez éventuellement ou non.

26voto

AndreyT Points 139512

(5) est "supérieure" (6), parce qu'elle définit GLOBAL_CONST_VAR tant que partie Intégrante de l'Expression Constante (ICE) dans toutes les unités de traduction. Par exemple, vous serez capable de l'utiliser comme matrice de taille et de cas de l'étiquette dans toutes les unités de traduction. Dans le cas de (6) GLOBAL_CONST_VAR sera une GLACE seulement en ce que l'unité de traduction où elle est définie et seulement après le point de définition. Dans d'autres unités de traduction, ça ne marchera pas comme de la GLACE.

Cependant, gardez à l'esprit que (5) donne GLOBAL_CONST_VAR liaison interne, ce qui signifie que l'adresse de l'identité" de l' GLOBAL_CONST_VAR sera différente dans chaque unité de traduction, c'est à dire l' &GLOBAL_CONST_VAR va vous donner une autre valeur du pointeur dans chaque unité de traduction. Dans la plupart des cas d'utilisation ce n'est pas grave, mais si vous aurez besoin d'un objet constant qui a globale et cohérente "de l'adresse de l'identité", alors vous devriez aller avec (6), pour autant sacrifier la GLACE-ness de la constante dans le processus.

Aussi, lorsque la GLACE-ness de la constante n'est pas un problème (pas une intégrale) et la taille du type développe plus (pas un type scalaire), puis (6) devient généralement une meilleure approche que les (5).

(2) n'est pas OK, car l' GLOBAL_CONST_VAR (2) a une liaison externe par défaut. Si vous le mettez dans le fichier d'en-tête, vous aurez généralement à la fin plusieurs définitions de l' GLOBAL_CONST_VAR, ce qui est une erreur. const objets en C++ ont une liaison interne par défaut, c'est pourquoi (5) fonctionne (et c'est pourquoi, comme je l'ai dit ci-dessus, vous obtenez une distincte, indépendante GLOBAL_CONST_VAR dans chaque unité de traduction).

5voto

Andras Zoltan Points 24996

Si ça va être une constante, alors vous devez marquer comme une constante, c'est pourquoi 2 est mauvais à mon avis.

Le compilateur peut utiliser la const de la nature de la valeur à développer certains des maths, ainsi que d'autres opérations que l'utilisation de la valeur.

Le choix entre les 5 et 6 - hmm; 5 seulement se sent mieux pour moi.

6), la valeur est inutilement détaché de cette déclaration.

En général, je voudrais avoir un ou plusieurs de ces en-têtes seulement définit des constantes etc, et puis pas d'autres "intelligent" trucs - nice léger en-têtes qui peuvent facilement être inclus.

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