C++ C++;定义跨文件常量的最佳方法

C++ C++;定义跨文件常量的最佳方法,c++,templates,constants,extern,C++,Templates,Constants,Extern,我正在做一个游戏,有一个有趣的问题。我想在一个文件中实现一些游戏范围的常量值。现在我有这样的事情: 常数.cpp extern const int BEGINNING_HEALTH = 10; extern const int BEGINNING_MANA = 5; 常数.hpp extern const int BEGINNING_HEALTH; extern const int BEGINNING_MANA; enum { BEGINNING_HEALTH = 10,

我正在做一个游戏,有一个有趣的问题。我想在一个文件中实现一些游戏范围的常量值。现在我有这样的事情:

常数.cpp

extern const int BEGINNING_HEALTH = 10;
extern const int BEGINNING_MANA = 5;
常数.hpp

extern const int BEGINNING_HEALTH;
extern const int BEGINNING_MANA;
  enum {
    BEGINNING_HEALTH = 10,
    BEGINNING_MANA = 5
  }
然后文件只包括“constants.hpp” 这非常有效,直到我需要使用其中一个常量作为模板参数,因为外部链接的常量不是有效的模板参数。 所以我的问题是,实现这些常量的最佳方法是什么?我担心简单地将常量放在头文件中会导致在每个翻译单元中定义它们。我不想使用宏

谢谢

枚举如何

常数.hpp

extern const int BEGINNING_HEALTH;
extern const int BEGINNING_MANA;
  enum {
    BEGINNING_HEALTH = 10,
    BEGINNING_MANA = 5
  }

也许是类似于静态类的东西

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

摆脱
extern
,您就完成了设置

这段代码在标题中工作得非常好,因为所有内容都是“真正的常量”,因此具有内部链接:

const int BEGINNING_HEALTH = 10;
const int BEGINNING_MANA = 5;
const char BEGINNING_NAME[] = "Fred";
const char *const BEGINNING_NAME2 = "Barney";
此代码不能安全地放入头文件中,因为每一行都有外部链接(显式链接或不是真正的常量):


大多数编译器只是不为常量POD值分配空间。他们将它们优化,并将它们当作“代码”定义为< /Cord>D,不是吗?< /P> < P>作为标题问题的快速回答,单模式是一种可能的最好的C++方法来定义跨文件常量,并确保对象只有一个实例。
至于模板参数问题,您需要传递类型而不是值。您的类型是“int”。

在.hpp文件中使用“static const int”,在.cpp文件中不添加任何内容(当然,除了您在那里的任何其他代码)。

一个简单的

#define BEGINNING_HEALTH 10
老兄,那些日子真是太好了。

哦,等等,那些日子还是那么美好

使用名称空间:

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

然后你可以使用as player.health=gamebeging::health

那没用。函数值不能用作模板参数。C++0x关键字
constexpr
应该可以解决这个问题。此外,C++还有一个命名空间,它对于一个“命名空间”常量来说是静态的,这似乎是一组简单常量的过多,并且不太可能解决模板实例化的问题。为什么不能用模板实例化来解决他的问题,因为它不是外部的,它是一个局部的。过度杀伤力是相对的,什么是1亿美元,10万美元,还是100美元的游戏预算?杰夫德,问题是你的答案没有意义。你想把一个“int”变成一个单态吗?int由值组成,而不是由标识组成。另一件可能让人们对你投反对票的事情是,他不想传递一个类型,而是想传递一个值给他的模板。你为什么说他不能?这个问题的标题本身就是个好问题。也许我真的需要多看看他的代码。请参阅以获取参考。“模板参数是一种特殊类型的参数,可用于将类型作为参数传递”。希望评论允许超链接。很好,http地址自动变成超链接。关闭,但仍然不完全相同。宏工作但常量不工作的示例:#定义FOO“FOO”;\const char*str=“bar”FOO;C和C++允许字符串字元标记的连接,但不允许字符串常量。这仅适用于积分常数。如果优化被禁用,浮点、双精度、字符*s和其他类型将被分配存储。@Tom:我不是这个意思。我指的是POD常量,而不是预处理器。我的意思是,除非您尝试获取其地址,否则符号和值的空格不存在。我认为POD正式包含浮点数和双精度,但浮点数和双精度通常不会以这种方式进行优化。我怀疑最后一个开头的\u NAME[]one中存在复制/粘贴错误。你想把它写成“开始”名字吗?你需要“静态”,否则你就不会得到内部链接,或者更理想的是,“值”的定义与“内联”的定义相同。@ C++中的Jim Buck常量有内部链接——不需要“静态”,可能不在模板参数上下文中做你所期望的……)rlbond需要这样。我们中的一些人喜欢我们的调试器显示“开始健康”而不是“10”。当您有printf()时,何时需要调试器?printf,#定义,下一步是什么。这是C++。