外部连接和全局变量
在C ++中,假设我们有这个头文件:
myglobals.h
#ifndef my_globals_h
#define my_globals_h
int monthsInYear = 12;
#endif
并且我们将它包含在多个实现文件中,那么我们将会收到编译错误,因为我们最终定义了'monthsInYear'多次,每个文件包含monthsInYear。
精细。 所以,如果我们修改我们的头并使我们的全局常量如此:
const int monthsInYear = 12;
那么我们的编译错误就会消失。 对此的解释,以及在此给出的例子是,const关键字在这里改变了monthsInYear到internal的链接,这意味着现在包括头的每个编译单元都有它自己的变量副本与内部联系,因此我们不再有多个定义。
现在,另一种方法是只用extern在头文件中声明变量,即:
extern int monthsInYear;
然后在包含头文件的其中一个实现文件中定义它,即:
#include "myglobals.h"
...
int monthsInYear = 12;
...
然后包括它在内的所有地方都在处理一个与外部联系的变量。
这很好,但我有点困惑的是使用const给它内部的联系,它解决了问题,并使用extern给它外部的联系,这也解决了问题! 这就像是说只要我们指定它,任何联系都可以做到。 最重要的是,当我们写道:
int monthsInYear = 12;
是不是已经是外部联系? 这就是为什么添加'const'将链接改为internal的原因?
在我看来,在这里使用'extern'的原因实际上解决了这个问题并不是因为它给了我们外部链接(我们已经有了),而是因为它允许我们仅仅声明变量而不定义它,否则我们不会无法做到,因为:
int monthsInYear = 12;
都声明和定义它,并且由于包含头文件有效地将代码复制粘贴到实现文件中,我们最终得到了多个定义。 相反,由于extern允许我们仅仅声明它,所以每次包含头时我们都会得到多个声明,这很好,因为我们被允许有多个声明,而不是多个定义。
我的理解是否正确? 对不起,如果这是非常明显的,但似乎extern至少做了三件事:
但是我所看到的很多资料并没有说清楚,当谈到使用extern来停止使用全局变量的'多重定义'错误时,并没有说明关键是将声明与定义分开。
对于一个非const
变量, extern
具有指定所述变量具有外部键(这是默认值)的影响,但它也将所定义成声明如果没有初始值设定-即extern int i;
实际上并没有定义i
。 ( extern int i = 5;
会,并希望生成一个编译器警告)。
当你写入extern int monthsInYear;
在多个源文件中(或者#include
到它们中,这相当于),它们都没有定义它。 int monthsInYear = 12;
仅在该源文件中定义变量。
存储类说明符是声明语法的decl-specifier-seq的一部分。 他们控制着声明引入名称的两个独立属性:存储时间和联系。
这是cppreference所说的,完全符合你的理解。
链接地址: http://www.djcxy.com/p/35329.html上一篇: extern, linkage and global variables
下一篇: How to define functions and data from another namespace, not in the global one?