2012-04-18 1 views
9

Ich schreibe ein Cocos2D-X-Spiel, wo der Spieler, Feinde und andere Charaktere ihre Attribute in einer CCMutableDictionary, die eine Art Dekorator-Klasse für std::map<std::string, CCObject*> ist, speichern. Auf einen Wert im Wörterbuch kann über die Methode CCMutableDictionary::objectForKey(const std::string& key) zugegriffen werden.Proper std :: string in einer Header-Datei zu tun?

nun in einer Header-Datei von vielen meiner CPP-Dateien enthalten, ich habe wie diese für den Zugriff auf Werte in den Wörterbuch, ein paar const char * const Saiten bekommt:

// in Constants.h 
const char* const kAttributeX = "x"; 
const char* const kAttributeY = "y"; 

// in a .cpp file 
CCObject* x = someDictionary->objectForKey(kAttributeX); 

Also, mich zu korrigieren, wenn ich bin falsch, aber std::string 's Kopie Konstruktor wird aufgerufen und eine temporäre std::string ist auf dem Stapel jedes Mal, wenn ich eine der oben genannten objectForKey Methoden mit einem const char* const aufrufen, richtig?

Wenn ja, ich fühle, dass es zur Laufzeit effizienter wäre, wenn diese konstanten Attributschlüssel bereits std::string Objekte wären. Aber wie mache ich das richtig Weg?

definieren sie in der constants.h Datei wie folgt aus fein kompiliert, aber ich habe das Gefühl, dass etwas einfach nicht richtig ist:

// in Constants.h 
const std::string kAttributeX = "x"; 
const std::string kAttributeY = "y"; 

Ich entschuldige mich, wenn diese Frage bereits gestellt hat. Ich konnte nicht die genaue Antwort finden, die ich hier auf StackOverflow suchte.

Antwort

18

Der Code, den Sie geschrieben haben, ist vollkommen in Ordnung, zumindest wie Sie nur #include die Constants.h Datei in nur einer Quelldatei. Wenn Sie die Headerdatei in mehreren Quelldateien verwenden, werden dieselben Variablen mehrmals definiert. Die korrekte Verwendung von Konstanten in Headerdateien sind sie in einen Header (Constants.h) zu spalten, die die Erklärungen der Variablen enthält, und eine Quelldatei (Constants.cpp), die enthält die Definitionen der Variablen:

Die Header-Datei:

#ifndef CONSTANTS_H 
#define CONSTANTS_H 

extern const std::string kAttributeX; 
extern const std::string kAttributeY; 

#endif 

die Quelldatei:

const std::string kAttributeX = "x"; 
const std::string kAttributeY = "y"; 
+0

Wenn also die Zeichenfolgen in einer CPP-Datei definiert sind, wann werden sie tatsächlich instanziiert? –

+0

@NatWeiss Sie werden zusammen mit allen anderen globalen Variablen instanziiert. –

+0

Gilt das Problem mit den mehrfach definierten Variablen, wenn sie "const char * const" waren? Ich bin mir ziemlich sicher, dass es nicht so ist, aber ich verstehe nicht warum. Was gibt "const char * const" das Privileg, an einem einzigen Ort definiert zu sein, der seinen Wert enthält (viel schöner, IMO, insbesondere in Bezug auf Wartung)? – Brent212

2

Ihre zweite Option bewirkt, dass jeder des va riables, die in jeder Übersetzungseinheit (cpp-Datei, die die Kopfzeile enthält) erstellt werden, die die Codegröße etwas erhöht und ein wenig Laufzeitkosten hinzufügt (die Konstruktion all dieser Strings während des Starts und deren Zerstörung während der Prozessbeendigung).

Die Lösung suggested by Joachim funktioniert, aber ich finde Variablen separat deklarieren und definieren, um ein bisschen ein Widerstand zu sein. Ich persönlich hasse es, mich selbst zu wiederholen, auch mag ich es nicht immer und immer wieder dasselbe zu sagen ...

Ich kenne keine gute Lösung dafür in C++, aber die Compiler, die ich mit allen gearbeitet habe Unterstütze etwas wie __declspec(selectany), so dass du die Variable in der Header-Datei definieren kannst und nur ein Objekt instanziiert bekommst (statt eines für jede Übersetzungseinheit).

__declspec(selectany) extern const std::string kAttributeX = "x"; 

(Für warum beide extern und const sehen this answer).

Sie haben immer noch den Nachteil, den Initialisierungspreis aller globalen Variablen während des Prozessstarts zu bezahlen. Dies ist in 101% der Fälle akzeptabel (geben oder nehmen Sie 2%), aber Sie können dies vermeiden, indem Sie faule Objekte verwenden (ich habe written about something similar here).

Verwandte Themen