静态VS在命名空间的非静态变量
我有一个命名空间foo
其中包含一个整数bar
,宣布所以...静态VS在命名空间的非静态变量
了foo.h:
namespace foo {
int bar;
}
现在,如果我有foo.h
只有一个文件,这工作得很好。但是当我从两个或多个文件中包含foo.h
时出现问题:出现连接器错误。我发现如果我宣布bar
为static
,我可以在一个以上的文件中包含foo.h
。这对我来说似乎很陌生,因为我不知道可以在名称空间内声明一个静态变量。 (这是什么意思?)
这是为什么?更重要的是,为什么不是它的工作没有static
?当在namespace
中使用时,static
是什么意思?
static
在不同的环境中有多种含义。在这个特定的上下文中,这意味着变量具有内部链接,因此包含该头文件的每个翻译单元都将拥有自己的变量副本。
请注意,尽管这样可以避免链接器错误,但它将为每个生成的对象文件(在不同的对象文件间都无法看到更改)保留单独的foo::bar
变量。
如果你想要一个变量,你应该在头文件中声明它为extern
,并在一个翻译单元中提供一个单一的定义。
当您声明一个变量为static
时,这意味着它的范围仅限于给定的翻译单元。没有static
范围是全球性的。
当一个变量声明为static
.h文件(在或不在namespace
;无所谓)内,并且包括在不同的cpp文件该头文件中,变量static
变得局部范围到每个.cpp
的文件。
所以现在,包含该头文件的每个.cpp文件都将拥有自己的该变量副本。
如果没有static
关键字,编译器将只生成该变量的一个副本,因此只要将头文件包含在多个.cpp文件中,链接器就会抱怨多个定义。
该问题是由变量的多个定义引起的。不同翻译单元中的定义相互冲突,就像多个非内联函数定义不起作用。
当您将变量设置为静态时,您会给出可变的内部链接,因此每个翻译单元都有自己的独立副本。
你可能真正想要的只是将声明放在一个头文件中(使用extern),然后将该定义放在一个实现文件中。
Upvote。是我的问题,并解决它:) – 2014-07-01 17:12:18