2010-10-14 4 views
0

Pour une application qui utilise un certain nombre de variables d'environnement, existe-t-il une sorte de convention ou «meilleure pratique» pour saisir des variables d'environnement et les placer dans un tas de const? Évidemment, je veux revenir à une valeur par défaut pour chaque variable d'environnement. En ce moment, en utilisant ce qui suit semble être une façon très désordonnée de le faire:C++ affecter const à la variable d'environnement ou à la valeur par défaut

char* x; 
const SOME_VARIABLE; 
if (NULL == (x = getenv("SOME_VARIABLE"))) 
    SOME_VARIABLE = 5; // default value 
else 
    SOME_VARIABLE = x; 

Je pourrais aussi écrire une fonction qui enveloppe getenv pour renvoyer une valeur par défaut si une variable d'environnement est vide, mais je ne suis pas sûr si c'est même la meilleure façon de le faire. Je pourrais également faire disparaître en utilisant const, mais cela ne semble pas non plus une bonne chose à faire.

Des pensées?

+0

En aparté, en nommant une variable ou constante en C++ tout en majuscules ne sont pas une bonne idée que par convention, tous les noms en majuscules sont utilisés par le Le préprocesseur et une macro de préprocesseur peuvent facilement modifier votre variable. –

+0

Ah, merci pour le conseil. J'avais l'impression que les constantes sont généralement supposées être toutes majuscules. – dav

+0

@Dav, vous avez probablement appris ce style à partir du code où toutes les constantes étaient des macros ('#define SOME_VARIABLE 5'). Ils sont en majuscules parce qu'ils sont des macros, pas parce qu'ils sont constants. –

Répondre

8

Que diriez-vous:

std::string GetEnvironmentVariableOrDefault(const std::string& variable_name, 
              const std::string& default_value) 
{ 
    const char* value = getenv(variable_name.c_str()); 
    return value ? value : default_value; 
} 

Utilisé comme:

const std::string some_variable = GetEnvironmentVariableOrDefault("SOME_VARIABLE", "5"); 
+0

On dirait que c'est la solution la plus simple. Merci. – dav

+0

Je suggérerais peut-être de surcharger le nom de la fonction à getenv() aussi, il serait plus naturel de lire. Cependant, le risque est que les gens iront le chercher dans les fichiers de documentation/d'en-tête getenv et pourraient manquer une fonction locale. – Drgabble

0

James McNellis a fourni une great answer, mais voici une opinion alternative:

Je pense que getenv() renvoie la valeur de l'environnement variable au moment du démarrage du programme. Si la variable d'environnement est modifiée après le démarrage du programme, getenv() retournera toujours l'ancienne valeur. Basé sur cela, une approche alternative peut être d'avoir une classe pour capturer toutes les variables d'environnement requises en tant qu'attributs. La classe est remplie au début du programme et fournit uniquement des méthodes d'accès (const-qualifiées). De cette façon, le getenv() est appelé exactement une fois pour chaque variable d'environnement. Du côté négatif, la classe prend de la place.

Dans l'approche alternative, qui n'utilise pas d'espace, getenv() est appelée chaque fois que la valeur d'une variable d'environnement est requise. Ce n'est pas que l'appel getenv() est cher (en fait je ne sais pas), mais il porte une fausse supposition au programmeur que la dernière valeur pourrait être retournée.

Il peut également être utile d'avoir une classe pour abstraire s'il existe une quelconque dépendance à l'utilisation des variables d'environnement, par ex.

if $OS = "SunOs" 
then 
    GCC="/bin/gcc" 
else 
    GCC="/usr/bin/gcc" 

(this is just an example though) 

Maintenant, une fonction qui ne se soucient pas $OS mais n'a besoin que $GCC, peut simplement se référer à envClass->get("GCC");

Juste une pensée.

+0

Bon point, bien que je ne compte pas utiliser ces constantes dans * trop * beaucoup d'endroits, donc je n'aurai probablement pas besoin d'appeler 'getenv' trop de fois. Une classe pour cela semble un peu trop lourde pour IMO, car cela ne fait que dupliquer ce que 'getenv' fait déjà. – dav

0

Je le fais généralement avec une classe qui charge les paramètres de configuration (soit à partir de l'environnement ou d'un fichier de configuration). J'instancie une instance globale unique au démarrage. Les paramètres du programme sont une méthode ou une propriété de l'objet de classe de configuration. Il est simple et quand vous écrivez du code, il est assez clair ce que vous vouliez:

if (configuration.ExitOnFailure && IsError()) 
    exit(); 
Questions connexes