根据我的理解,你在.cpp文件中而不是在.h中初始化静态成员的原因是这样就没有获得该成员的几个实例的风险。接下来是这个例子:
//Foo.h
#ifndef FOO_H
#define FOO_H
class Foo{
static int a;
};
int Foo::a = 95;
#endif
预处理程序指令确保此.h文件仅编译一次,这确保只有一个静态成员实例。是否可以这样做而不是在.cpp文件中启动静态成员?
答案 0 :(得分:7)
不,它只确保每个编译单元(Foo.h
文件)包含.cpp
一次。不在整个项目中。您应该在Foo.cpp
答案 1 :(得分:4)
考虑使用两个包含标头的源代码文件a.cpp
和b.cpp
。由于它们是相互独立编译的,因此标题保护不起作用,最终会有两个目标文件a.o
和b.o
,都定义{{1} }。试图将它们链接在一起会失败。
答案 2 :(得分:3)
如果标头包含在多个.cpp
文件(翻译单元)中,这将导致链接器错误:
//a.cpp
#include <Foo.h>
//b.cpp
#include <Foo.h>
编译后,a.obj
包含Foo::a
的定义,b.obj
包含Foo::b
的定义。如果尝试将这两个.obj
文件链接到单个二进制文件中,则会发生多重定义错误。
答案 3 :(得分:1)
不,包含保护确保每个编译单元一次最多包含一个标头。如果您的程序有多个编译单元(.cpp
文件),包括标题,那么您最终会得到Foo::a
的多个定义。