...
#include "test1.h"
int main(..)
{
count << aaa <<endl;
}
Run Code Online (Sandbox Code Playgroud)
aaa是在定义中test1.h,我没有使用extern关键字,但仍然可以参考aaa.
所以我怀疑是否extern真的有必要?
sel*_*tze 13
extern有它的用途.但它主要涉及不满意的"全球变量".背后的主要思想extern是用外部联系来宣告事物.因此,它与之相反static.但在许多情况下,外部链接是默认链接,因此extern在这些情况下您不需要.另一个用途extern是:它可以将定义转换为声明.例子:
extern int i; // Declaration of i with external linkage
// (only tells the compiler about the existence of i)
int i; // Definition of i with external linkage
// (actually reserves memory, should not be in a header file)
const int f = 3; // Definition of f with internal linkage (due to const)
// (This applies to C++ only, not C. In C f would have
// external linkage.) In C++ it's perfectly fine to put
// somethibng like this into a header file.
extern const int g; // Declaration of g with external linkage
// could be placed into a header file
extern const int g = 3; // Definition of g with external linkage
// Not supposed to be in a header file
static int t; // Definition of t with internal linkage.
// may appear anywhere. Every translation unit that
// has a line like this has its very own t object.
Run Code Online (Sandbox Code Playgroud)
你看,它相当复杂.有两个正交的概念:链接(外部与内部)以及声明与定义的关系.该extern关键字可能会影响.关于联系,它是相反的static.但是意义static也是超载的 - 并且 - 取决于上下文 - 是否控制联系.它的另一个作用是控制对象的生命周期("静态生命周期").但是在全球范围内,所有变量都已经具有静态生命周期,并且有些人认为回收关键字来控制链接是个好主意(这只是猜测).
链接基本上是在"命名空间范围"声明/定义的对象或函数的属性.如果它具有内部链接,则不能通过其他翻译单元的名称直接访问它.如果它具有外部链接,则所有翻译单元中只应有一个定义(有例外,请参阅单定义规则).
我发现组织数据的最佳方法是遵循两个简单的规则:
通过声明,我的意思是通知编译器存在的东西,但不为它们分配存储.这包括typedef,struct,extern等.
通过定义,我通常意味着"为...分配空间",int等等.
如果你有一个像这样的行:
int aaa;
Run Code Online (Sandbox Code Playgroud)
在头文件中,每个编译单元(基本上定义为编译器的输入流 - C文件及其带来的所有内容#include,递归)将获得自己的副本.如果将两个具有相同符号定义的目标文件链接在一起(除非在某些有限的情况下const),这将导致问题.
更好的方法是aaa在一个C文件中定义该变量,然后放入:
extern int aaa;
Run Code Online (Sandbox Code Playgroud)
在您的头文件中.
请注意,如果您的头文件仅包含在一个C文件中,则这不是问题.但是,在这种情况下,我可能甚至没有头文件.在我看来,头文件只是用于在编译单元之间共享内容.
如果你的test1.h有aaa的定义并且你想将头文件包含到多个翻译单元中,那么你将遇到多个定义错误,除非aaa是常量.最好在cpp文件中定义aaa,并在头文件中添加extern定义,可以将其作为标题添加到其他文件中.
用于在头文件中具有变量和常量的Thumb规则
extern int a ;//Data declarations
const float pi = 3.141593 ;//Constant definitions
Run Code Online (Sandbox Code Playgroud)
由于常量在c ++中具有内部链接,因此在翻译单元中定义的任何常量对于其他翻译单元是不可见的,但对于具有外部链接的变量则不是这样,即,它们对于其他翻译单元是可见的.将变量的定义放在标题中,在其他翻译单元中共享将导致变量的多个定义,从而导致多个定义错误.