2009-03-13 15 views
10

私はゲームに取り組んでおり、面白い質問があります。私は1つのファイルに実装したいいくつかのゲーム全体の定数値を持っています。今、私はこのようなものがあります:クロスファイル定数を定義するにはC++の最良の方法

constants.cpp

extern const int BEGINNING_HEALTH = 10; 
extern const int BEGINNING_MANA = 5; 

constants.hpp

extern const int BEGINNING_HEALTH; 
extern const int BEGINNING_MANA; 

をそしてちょうどまで、これは素晴らしい仕事をしていた "constants.hppを" #includeファイル外部リンク定数は有効なテンプレートパラメータではないので、定数の1つをテンプレートパラメータとして使用する必要がありました。 私の質問は、これらの定数を実装する最良の方法は何ですか?ヘッダーファイルに定数を入れるだけで、それぞれの翻訳単位で定義されることになるのではないかと思います。私はマクロを使いたくありません。

ありがとうございました

答えて

19

externを取り除くと設定されています。

すべては「本当に定数」であるため、内部リンケージを持っているので、このコードは、ヘッダで完全に正常に動作します:各行が(外部リンケージを持っているので、

const int BEGINNING_HEALTH = 10; 
const int BEGINNING_MANA = 5; 
const char BEGINNING_NAME[] = "Fred"; 
const char *const BEGINNING_NAME2 = "Barney"; 

このコードは、安全に、ヘッダファイルに入れることができません明示的にまたは真に不変であるため):

extern const int BEGINNING_HEALTH = 10; 
extern const int BEGINNING_MANA = 5; 
const char *BEGINNING_NAME = "Wilma"; // the characters are const, but the pointer isn't 
+0

最後のBEGINNING_NAME [] 1にコピー/ペーストのバグがあると思われます。 BEGINNING_NAMEと書いてみましたか? –

+0

あなたは正しい、修正されています。ありがとう。 – Tom

+0

"静的"が必要です。そうでなければ、内部リンケージや、理想的には "#define"に相当する値がインライン化されます。 –

10

enumsはどうですか?

constants.hppおそらく

enum { 
    BEGINNING_HEALTH = 10, 
    BEGINNING_MANA = 5 
    } 
-2

静的クラスの線に沿って何か?

class CONSTANTS { 
public: 
static inline int getMana() { return 10;}; 
}; 
+0

これは役に立ちません。関数値はテンプレートパラメータとして使用できません。 C++ 0xのキーワード 'constexpr'はこれを回避することになっています。 さらに、C++には名前空間があります。これは "名前空間"定数の静的クラスをスーパーオーナにしています。 – Tom

+0

*優れた* ...私は基本的な校正能力が不足しています:) – Tom

0

ほとんどのコンパイラは、const POD値のためのスペースを割り当てません。彼らはそれらを最適化し、彼らが#define dであったかのように扱いますか?

+0

閉じるが、それでも全く同じではありません。マクロは機能するが定数はしない例:#define FOO "foo"; \ const char * str = "bar" FOO; CおよびC++では、文字列リテラルトークンは連結できますが、文字列定数は連結できません。 – Tom

+0

これは整数定数に対してのみ当てはまります。 float、doubles、char *などの型は、最適化が無効な場合は記憶域が割り当てられます。 –

+0

@トム:それは私が意味するものではありません。私はプリプロセッサのマジックではなく、PODの定数を意味していました。あなたがその住所を取ろうとしない限り、シンボルとその値のためのスペースは存在しないという意味で私は意味しました。 – greyfade

-5

タイトルの質問への簡単な答えとして、クロスファイル定数を定義し、オブジェクトのインスタンスを1つしか保証しないシングルトンパターンがベストなC++の方法です。

テンプレートパラメータの問題ではなく、値ではなくタイプを渡す必要があります。あなたのタイプは "int"です。

+0

これは、単純な定数のセットには過剰なもののようで、テンプレートのインスタンス化に関する問題を解決する可能性は低いです。 – Eclipse

+0

テンプレートのインスタンス化で問題が解決しないのはなぜですか?externではないため、ローカルになります。残虐行為は相対的なもので、品質の観点は$ 100M、$ 100K、または$ 100のゲーム予算ですか? – jeffD

+0

jeffD、あなたの答えが理にかなっていないという問題があります。シングルトンを「int」にしたいですか? intは値で構成され、同一性ではありません。おそらく人々をあなたに下降させるもう一つのことは、型を渡すことを望まず、テンプレートに価値を渡すことです。なぜ彼はできないと言いますか? –

6

.hppファイルで "static const int"を使用し、.cppファイルには何も入れないでください(ただし、他のコードはもちろんあります)。これまでの単純なに何が起こった

0

#define BEGINNING_HEALTH 10 

マンは、これらの日でした。
ああ待って、そのはまだ日です!

+0

それは、あなたがテンプレートパラメータの文脈で期待していることをしないかもしれません... :) rlbondはそれを必要とします。 –

+4

私たちの中には、デバッガが「10」ではなく「BEGINNING_HEALTH」と表示されるものがあります。 –

+0

printf()を使っているときにデバッガが必要なのはいつですか? slacy

3

名前空間のメイク使用:

namespace GameBeginning { 
    const int HEALTH = 10; 
    const int MANA = 5; 
}; 

その後、uはプレーヤーとして使用することができます。ヘルス= GameBeginning :: HEALTH;

関連する問題