小编lem*_*ult的帖子

外部,联系和全局变量

在C++中,假设我们有这个头文件:

myglobals.h

#ifndef my_globals_h
#define my_globals_h

int monthsInYear = 12;

#endif
Run Code Online (Sandbox Code Playgroud)

并且我们将它包含在多个实现文件中,然后我们将得到编译错误,因为我们最终定义了多次'monthsInYear',每个文件中包含了monthsInYear一次.

精细.因此,如果我们修改我们的标头并创建我们的全局const,就像这样:

const int monthsInYear = 12;
Run Code Online (Sandbox Code Playgroud)

然后我们的编译错误就消失了.正如我所理解的那样,这里给出的解释是,这里的const关键字将monthsInYear的链接更改为internal,这意味着现在包含头的每个编译单元现在都有自己的变量副本内部联系,因此我们不再有多个定义.

现在,另一种方法是仅使用extern在头部声明变量,即:

extern int monthsInYear;
Run Code Online (Sandbox Code Playgroud)

然后在包含标题的其中一个实现文件中定义它,即:

#include "myglobals.h"
...
int monthsInYear = 12;
...
Run Code Online (Sandbox Code Playgroud)

然后包含它的每个地方都在处理一个带有外部链接的变量.

这很好,但我有点困惑的是,使用const给它内部链接,修复问题,并使用extern给它外部链接,这也解决了问题!这就像说任何联系都会做,只要我们指定它.最重要的是,当我们写道:

int monthsInYear = 12;
Run Code Online (Sandbox Code Playgroud)

是不是外部的联系?这就是为什么添加'const' 会将链接更改为内部?

在我看来,在这里使用'extern'的原因实际上解决了问题并不是因为它给了我们外部链接(我们已经有了),而是因为它允许我们仅仅声明变量而不定义它,否则我们不会因为:所以能做到:

int monthsInYear = 12;
Run Code Online (Sandbox Code Playgroud)

声明定义它,并且因为包含标题有效地将代码复制粘贴到实现文件中,所以我们最终得到了多个定义.相反,由于extern允许我们仅仅声明它,每次我们包含头时都会得到多个声明,这很好,因为我们被允许有多个声明,而不是多个定义.

我的理解在这里是否正确?对不起,如果这是非常明显的,但看起来extern至少做了三件事:

  • 指定外部链接
  • 允许声明对象而不定义它们
  • 指定静态存储持续时间

但是我看到的很多来源都没有说清楚,当谈到使用extern来阻止全局变量的"多重定义"错误时,并不清楚关键是将声明与定义分开.

c++

9
推荐指数
1
解决办法
687
查看次数

标签 统计

c++ ×1