2012-08-30 3 views
3

Ce qui est une façon de déclarer une chaîne const est plus recommandé?variable globale statique V classe

  1. Est de déclarer la variable globale à la portée du fichier.
  2. de la déclarer globale à la classe.

La variable ne sera utilisée que dans les fonctions membres de la classe. J'ai tendance à me sentir mieux car il est spécifique aux fonctions membres.

A.cpp 
--------------------- 
static const std::string hello_str = "Hello"; 

void A::print() 
{ 
    std::cout << hello_str; 
} 

(OR)

A.h 
--------------------- 
class A{ 
public: 
    static const std::string hello_str; 
    void print(); 
} 

A.cpp 
--------------------- 
const std::string A::hello_str = "Hello"; 

void A::print() 
{ 
    std::cout << A::hello_str; 
} 

Modifier -1:

Permettez-moi de dire que le contenu de hello_str peuvent changer. Par exemple. la chaîne est mise à jour manuellement par le développeur chaque fois qu'il apporte une modification au fichier.

Dans ce cas, serait-il logique de garder l'initialisation variable dans une fonction? Il peut ne pas être clair/évident pour l'utilisateur de mettre à jour la chaîne. Si elle était conservée globalement dans le fichier (1) ou dans la classe (2), les autres développeurs peuvent "identifier" & modifier cette chaîne.

Étant donné le cas d'utilisation ci-dessus, recommandez-vous encore avoir une fonction pour retourner la chaîne? Ou puis-je utiliser la variable statique de niveau classe (avec un spécificateur d'accès privé)?

Répondre

4

un espace de noms anonyme est une autre option:

A.cpp

namespace { 
    const std::string hello_str("Hello"); 
} 

void A::print() { 
    std::cout << hello_str; 
} 

mais vous devriez vraiment envelopper que dans une fonction d'initialisation différée.

qui prendrait la forme:

A.h 
--------------------- 
class A{ 
public: 
    static const std::string& hello_str(); 
    void print(); 
} 

A.cpp 
--------------------- 
const std::string& A::hello_str() { 
    static const std::string str("Hello"); // << constructed on first call of A::hello_str() 
    return str; 
} 

void A::print() { 
    std::cout << A::hello_str(); 
} 

dans ce cas, vous pouvez également revenir simplement en valeur et éviter tout à fait statique/global. votre implémentation de bibliothèque C++ std peut utiliser ce que l'on appelle une "optimisation de petite chaîne" - si c'est le cas, aucune allocation de tas ne serait nécessaire pour créer ou déplacer une chaîne aussi courte.

Notez également que vos deux exemples ne sont pas identiques; l'un est effectivement privé, et l'autre est visible publiquement.

finalement, vous devez utiliser ni l'approche que vous avez proposée. considérez un static dans une fonction pour une initialisation paresseuse, ou (encore mieux dans de nombreux cas) un retour par valeur.

pour répondre à votre question initiale: je privilégie la déclaration dans la classe, mais privée. Je trouve cela plus facile à maintenir dans le cas où les implémentations se déplacent. et bien sûr, si cette statique dans le cpp est en quelque sorte accessible aux implémentations extérieures, alors vous pourriez vouloir aussi le déclarer comme privé dans la classe afin que les autres ne puissent pas y accéder.

+0

Peut-on expliquer que «l'un est effectivement privé et l'autre est visible publiquement». - Je pensais que les deux sont 1 et 2 sont publics. "Je suis favorable à la déclaration dans la classe, mais privée." - Comprendre cette partie, que seul le membre func y accède et pas de main (autre fonction membre de la classe) "Je trouve cela plus facile à maintenir dans le cas où les implémentations se déplacent et bien sûr, si cette statique dans le cpp est en quelque sorte accessible aux implémentations extérieures, alors vous pouvez aussi le déclarer comme privé dans la classe afin que les autres ne puissent pas y accéder. " - Peut-on expliquer cela et/ou me donner un exemple? –

+1

@KingkongJnr c'est juste le cas évident: dans # 1, le 'static' peut être accédé par n'importe quoi dans A.cpp qui ne le précède pas. si A.cpp contient seulement des définitions de la classe A, alors c'est ce que j'ai appelé "effectivement privé". la visibilité et l'accès à la statique est * restreint *. C'est une approche commune que les programmeurs utilisent pour leurs fonctions/données privées. par exemple: 'main()' n'a pas pu accéder à cette static, sauf si main était défini dans A.cpp. – justin

+0

@KingkongJnr 'print', déclaré' private' et foo est public ici: 'class A {\ n public: void foo(); \ n privé: \ n void print(); \ n}; ' – justin

2

règle simple:

  • Le string appartient logiquement à la classe il devrait donc être un membre de la classe.
  • Toutes les instances de la part de la classe la même chaîne par conséquent, il appartient à la classe et non une instance spécifique de la classe (toutes les instances partagent même chaîne), alors faites un membre static.

Cela vous donne l'avantage:

  • Seuls les membres de la classe qui ont besoin d'accéder à la chaîne auront accès, à la différence si vous déclarez comme une chaîne mondiale.