Bonne façon de le faire const std::string dans un fichier d'en-tête?
Je suis en train d'écrire un Cocos2D-X jeu où le joueur, les ennemis et les autres personnages de stocker leurs attributs dans un CCMutableDictionary
, qui est en quelque sorte d'un décorateur de classe pour std::map<std::string, CCObject*>
. Une valeur dans le dictionnaire peut être consulté via le CCMutableDictionary::objectForKey(const std::string& key)
méthode.
Maintenant, dans un fichier d'en-tête inclus par beaucoup de mes .fichiers cpp, j'ai un peu de const char * const
chaînes pour accéder aux valeurs dans les dictionnaires, comme ceci:
//in Constants.h
const char* const kAttributeX = "x";
const char* const kAttributeY = "y";
//in a .cpp file
CCObject* x = someDictionary->objectForKey(kAttributeX);
Donc, corrigez-moi si je me trompe, mais std::string
'constructeur de copie est appelé et temporaire std::string
est sur la pile à chaque fois que j'appel un des ci-dessus objectForKey
méthodes à l'aide d'un const char* const
, droit?
Si oui, je pense qu'il serait plus efficace lors de l'exécution si ceux attribut constant clés ont été déjà std::string
objets. Mais comment puis-je faire pour que l' droit?
Définir les Constantes.h fichier comme suit compile bien, mais j'ai le sentiment que quelque chose n'est pas droite:
//in Constants.h
const std::string kAttributeX = "x";
const std::string kAttributeY = "y";
Toutes mes excuses si cette question a déjà été posée. Je n'arrivais pas à trouver la réponse exacte je cherche ici sur StackOverflow.
OriginalL'auteur Nathanael Weiss | 2012-04-18
Vous devez vous connecter pour publier un commentaire.
Le code que vous avez écrit est parfaitement bien, à moins que vous ne
#include
laConstants.h
de fichiers dans un seul fichier source. Si vous utilisez le fichier d'en-tête dans plusieurs fichiers sources, vous aurez les mêmes variables définies plusieurs fois. L'utilisation correcte de constantes dans les fichiers d'en-tête sont à diviser en-tête (Constants.h
) qui contient le déclarations des variables, et un fichier source (Constants.cpp
) qui contient le définitions des variables:Le fichier d'en-tête:
Le fichier source:
Ils seront instanciés avec l'ensemble des autres variables globales.
Le problème avec les variables définies plusieurs fois le même s'ils ont été "const char* const"? Je suis sûr que ça ne marche pas, mais je ne comprends pas pourquoi. Ce qui donne "const char* const" le privilège d'être définie dans un emplacement unique qui comprend sa valeur (beaucoup plus agréable, de l'OMI, en particulier en termes de maintenance)?
Vous pouvez également utiliser
static const std::string kAttributeX = "x";
dans l'en-tête. Ensuite, vous n'aurez pas besoin d'instancier ces constantes dans un fichier source. Chaque unité de compilation qui #inclut l'en-tête de sa propre copie de l'objet constant, mais comme il n'est pas visible de l'extérieur, il n'y aura pas dupliquer le symbole des erreurs.J'ajouterais juste pour être complet, si votre
const
les variables définies dans le cadre d'un espace de noms, vous avez besoin de ré-ouvrir dans le fichier source.OriginalL'auteur
Votre deuxième option permet à chacune des variables à être créé dans chaque unité de traduction (rpc fichier qui contient l'en-tête) qui entraîne une légère augmentation de la taille du code ainsi que l'ajout d'un peu de runtime coût (construction de tous ceux de la chaîne lors de son lancement et la destruction pendant la fin du processus).
La solution suggéré par Joachim fonctionne, mais je trouve la déclaration et la définition des variables séparément pour être un peu monotone. Personnellement, je déteste me répéter, aussi je n'aime pas dire la même chose, encore et encore...
Je ne sais pas d'une bonne solution en C++ bonne, mais les compilateurs j'ai travaillé avec tous les support de quelque chose comme
__declspec( selectany )
de sorte que vous pouvez définir la variable dans le fichier d'en-tête et un seul objet instancié (plutôt qu'une pour chaque unité de traduction).(Pour laquelle les deux
extern
etconst
voir cette réponse).Vous avez encore l'inconvénient de payer l'initialisation prix de toutes les variables globales au cours du processus de lancement. Ceci est acceptable à 101% du temps (donner ou prendre 2%), mais vous pouvez éviter cela en utilisant les paresseux objets (j'ai écrit à propos de quelque chose de similaire ici).
OriginalL'auteur