2012-04-18 13 views
9

私はCocos2D-Xゲームを書いています。プレイヤー、敵、そして他のキャラクターが属性をCCMutableDictionaryに保存しています。これは、std::map<std::string, CCObject*>のデコレータークラスです。辞書の値は、CCMutableDictionary::objectForKey(const std::string& key)メソッドを介してアクセスできます。ヘッダファイルにconst std :: stringを行う適切な方法は?

さて、私の.cppファイルの多くが含まれるヘッダ・ファイルで、私はこのように、辞書内の値にアクセスするためのいくつかのconst char * const文字列を持っている:

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

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

ので、なら、私を修正I上記のobjectForKeyメソッドの1つをconst char* constを使用して呼び出すたびに、std::stringのコピーコンストラクタが呼び出されており、一時的なstd::stringがスタックにあります。

もしそうなら、定数属性キーが既にstd::stringのオブジェクトであれば、実行時に効率的になると思います。しかし、どうすればいいのですか

以下の罰金コンパイルのようなファイルConstants.hでそれらを定義するが、私は何かがちょうどではないことを感じてい:この質問は、すでに依頼された場合

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

私の謝罪を。私はStackOverflowでここで探していた正確な答えを見つけることができなかった。

答えて

18

あなたが書いたコードは少なくとも#includeConstants.hのファイルが1つのソースファイルにしかないので、完璧です。ヘッダーファイルを複数のソースファイルで使用すると、同じ変数が複数回定義されます。ヘッダファイルの定数の正しい使い方は定義変数のが含まれてい宣言変数の、およびソースファイル(Constants.cpp)を含むヘッダー(Constants.h)にそれらを分割する、次のとおりです。

ヘッダファイル:

#ifndef CONSTANTS_H 
#define CONSTANTS_H 

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

#endif 

ソースファイル:

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

したがって、文字列が.cppファイルで定義されている場合、実際にインスタンス化されるのはいつですか? –

+0

@NatWeissこれらは、他のすべてのグローバル変数とともにインスタンス化されます。 –

+0

"const char * const"のときに複数回定義された変数の問題は当てはまりますか?私はそれがないと確信していますが、私は理由を理解していません。 const char * constに、その値を含む単一の場所で定義される特権を与えるもの(特に保守の面でIMO、もっと良い)? – Brent212

2

あなたの目のオプションは、VAのそれぞれの原因となりますコードサイズをわずかに増やすだけでなく、実行時のコストを少し追加する(すべての文字列を起動時に構築し、プロセス終了時にそれらを破壊する)すべての翻訳単位(ヘッダーを含むcppファイル)で作成されます。

ソリューションsuggested by Joachimが機能しますが、変数を宣言して定義すると、ドラッグが少ししかないことがわかります。私は個人的に自分自身を繰り返すことを嫌い、同じことを何度も繰り返すのは好きではありません...

これはC++の適切な解決策ではありませんが、ヘッダーファイルに変数を定義し、インスタンス化されたオブジェクトを1つだけ取得できるように、__declspec(selectany)のようなものをサポートします(各翻訳単位に1つずつではなく)。

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

externconst両方がthis answerを参照してください理由のために)。

プロセスの起動中に、すべてのグローバル変数の初期化価格を支払うという欠点はまだあります。これは時間の101%(2%を与える、または取る)ですが、遅延オブジェクト(私はwritten about something similar hereを使っています)を使ってこれを避けることができます。

関連する問題