my_test.h
#ifndef MY_TEST
#define MY_TEST
struct obj {
int x;
int y;
};
class A {
private:
const static int a=100;
const static obj b;
};
const obj A::b={1,2};
#endif
使用此头文件编译cpp时,会出现错误'multiple definition of 'A::b'
。
A::a
没有产生错误? (我无法在const static obj b={1,2}
)class A
醇>
答案 0 :(得分:4)
为什么我已经使用了守卫宏?
页眉防护仅阻止在同一 translation unit 中多次包含头文件内容而不是多个翻译单元。
编译器允许为什么
A::a
没有错误消息(我无法在const static obj b={1,2}
中编写代码class A
)
In-class initialization 作为const文字类型的静态数据成员的特例。你的例子是In-class初始化。
const A::b
在每个翻译单元中定义相同的符号名称,其中包含标题,因此会破坏 one definition rule 。
您需要将定义移动到一个且只有一个源cpp文件,以便只定义一次。
答案 1 :(得分:1)
Alok已经回答了你的问题,但这里有一些简单的经验法则,易于记忆:
因此,静态成员需要在.h文件中声明,然后在.cpp文件中定义。在您的情况下,修复声明的语法,然后将它们移动到“my_test.cpp”文件。
答案 2 :(得分:0)
问题是您对A::b
的定义不包含类型。要成为有效的定义,它应该是:
const obj A::b = {1, 2};
这将消除编译错误,但如果将此标头包含在多个源文件中,您仍会遇到链接器错误,因为A::b
将被多次定义。您应该将定义移动到.cpp文件中。
答案 3 :(得分:0)
无论您是否有头文件保护,将初始化放在头文件中都意味着您将在包含该头文件的每个源文件中获得A::b
的实例。因此链接器错误。
所以,一般来说,这是可能的,但不是一个好主意。