如果我在头文件中定义常量变量,如下所示...
extern const double PI = 3.1415926535;
extern const double PI_under_180 = 180.0f / PI;
extern const double PI_over_180 = PI/180.0f;
我得到以下错误
1>MyDirectX.obj : error LNK2005: "double const PI" (?PI@@3NB) already defined in main.obj
1>MyDirectX.obj : error LNK2005: "double const PI_under_180" (?PI_under_180@@3NB) already defined in main.obj
1>MyDirectX.obj : error LNK2005: "double const PI_over_180" (?PI_over_180@@3NB) already defined in main.obj
1>MyGame.obj : error LNK2005: "double const PI" (?PI@@3NB) already defined in main.obj
1>MyGame.obj : error LNK2005: "double const PI_under_180" (?PI_under_180@@3NB) already defined in main.obj
1>MyGame.obj : error LNK2005: "double const PI_over_180" (?PI_over_180@@3NB) already defined in main.obj
但是如果我从标题中删除这些常量,并将它们放入包含标题的文档中,如下所示……
const double PI = 3.1415926535;
const double PI_under_180 = 180.0f / PI;
const double PI_over_180 = PI/180.0f;
它起作用了
有人知道我可能做错了什么吗?
谢谢
发布于 2010-02-25 03:01:29
它们的extern
存储类几乎可以肯定是您所看到的问题的原因。如果您删除它,代码可能会很好(至少在这方面是这样)。
编辑:我刚刚注意到您已经将其标记为C和C++。在这方面,C和C++确实有很大的不同(但从错误消息来看,您显然是编译为C++,而不是C)。在C++中,您希望删除extern
,因为(默认情况下) const
变量具有static
存储类。这意味着每个源文件(翻译单元)都将拥有自己的变量“副本”,并且不同文件中的定义之间不会有任何冲突。由于您(可能)只使用值,而不是将它们视为变量,因此拥有多个“副本”不会有任何坏处--它们都不会被分配存储空间。
在C中,extern
是非常不同的,删除extern
不会有任何实际的区别,因为缺省情况下它们将是extern
。在这种情况下,您确实需要在一个位置初始化变量,并在头文件中声明它们为extern。或者,您可以添加static
存储类,当您从标头中删除extern
时,C++将默认添加该存储类。
发布于 2010-02-25 05:01:11
下面有很多不正确的回答。正确的是那些告诉你删除extern
的,就像sellibitze在他的评论中所说的那样。
因为它们被声明为const,所以在头文件中定义是没有问题的。C++将内联内置类型的常量,除非你试图获取它的地址(指向常量的指针),在这种情况下,它将使用static
链接实例化它,然后你也可以在不同的模块中获得多个实例化,但除非你希望所有指向同一常量的指针都有相同的地址,否则这不是问题。
发布于 2010-02-25 03:02:29
您需要在头文件中声明contants,然后在您的一个代码文件中定义它们。如果您没有在任何地方声明它们,那么当它试图将声明绑定到实际定义时,就会出现链接器错误。你也可以使用#ifdef语句在头文件中有一个定义。
确保在每个需要它们的人都包含的头中声明它们,并确保它们只定义一次。
雅各布
https://stackoverflow.com/questions/2328671
复制相似问题