静态VS在命名空间的非静态变量(static vs non-static variables in

2019-06-26 11:35发布

我有一个命名空间foo其中包含一个整数bar ,宣告所以...

foo.h中:

namespace foo {
    int bar;
}

现在,如果我包括foo.h中只有一个文件,这个工作得很好。 但是,当我有一个问题出现foo.h我得到一个链接错误:从两个或多个文件。 我想通了,如果我声明barstatic ,我可以包括foo.h的多个文件。 这似乎很奇怪,我,因为我不知道,人们可以声明命名空间内的静态变量。 (那有什么意思?)

为什么这项工作? 更重要的是,为何它没有工作没有 static ? 什么static在使用时平均namespace

Answer 1:

有多重含义static在不同的上下文。 在此特定情况下它意味着该变量具有内部连接,因此,其包括头部将有它的可变的自己的副本每个翻译单元。

请注意,虽然这无声的链接错误,它会做这样保持一个独立的foo::bar为生成的目标文件中的每一个(变化将不会在不同的目标文件可见)变量。

如果你想要一个变量,你应该把它声明为extern在头,并提供一个转换单元的单一定义。



Answer 2:

当一个变量声明为static ,这意味着其范围仅限于给定的翻译单元 。 如果没有static的范围是全球性的。

当一个变量声明为static .h文件内(在有或没有namespace ;无所谓),并且包括在不同的.cpp文件头文件中, static变量变成局部范围到每一个的.cpp文件。
所以,现在,这包括每头.cpp文件都会有自己该变量的副本。

如果没有static关键字,编译器将生成唯一一个变量的副本,因此只要您在多个的.cpp头文件中的文件,链接器将抱怨多重定义。



Answer 3:

该问题通过具有可变的多个定义而引起的。 在相互不同的翻译单位冲突的定义,就像多个非内联函数定义是行不通的。

当你让你给变量内部连接的静态变量,因此每个翻译单元都有自己独立的副本。

你可能实际上要的是只放声明在一个头(使用EXTERN),然后把定义在实现文件。



Answer 4:

还要注意的是const int在C ++已经命名空间(全局)范围static隐含默认添加: 在C ++头定义常量变量

为了更好地理解正在发生的事情,做一个readelf在编译的中间ELF对象文件,你会看到两次或没有明确的定义符号。 这里是一个详细的例子: 什么是“静态”的意思是用C?



文章来源: static vs non-static variables in namespace