C++的全局变量,静态全局变量,常全局变量定义与声明

时间:2022-07-02 08:55:40

头文件中变量如果没有初始化就是声明;初始化了就是定义。在C++语言中,变量有且只能有一次定义,但是可以声明多次,使用变量前必须定义或声明。

再说到这些变量的声明与定义前,要知道这些变量的链接性:

外部全局变量                  外部连接性   可以被extern

静态全局变量(static)  内部连接性   不能被extern

常全局变量(const)      内部连接性  在之前加上extern就变成了外部连接性,就可以被其他的文件extern了


声明:(可以放在头文件)没有开辟内存的定义,类型定义,比如类的定义,结构体的定义,它是定义一个数据类型而

定义:(不可放在头文件)开辟了内存的定义,数据定义,比如类对象定义,变量定义

一般来说:

不分配内存的,放在头文件
分配内存的放在cpp文件,防止重复定义,当然也要看变量的连接性,内部连接性的可以放在头文件定义。

  变量、函数、类,在使用之前都必须声明,包含头文件,如果a.h包含了b.h,在a.h里面就对b.h里面的声明重新声明了,这也是不能在头文件里面定义变量与函数的原因(防止重复定义),当然内部链接性的变量和内联函数除外。


       C++是不允许在头文件里定义一个外部全局变量(声明可以,比如在源文件定义,在头文件extern声明,像int a;这样不算声明,是定义,全局变量默认赋值0),因为当这个头文件被多个别的文件(.cpp或.h)包含的时候,会重复定义这个全局变量,而外部全局变量是外部连接性,别的文件可以互相访问地址,这个与变量有且只能有一次定义(单一定义规则)矛盾,会造成编译出错,即使你在其他的文件里使用extern都不行,因为是其他文件包含这个定义了外部全局变量的头文件。若是真的需要外部全局变量,可以在源文件定义一个外部全局变量,在该源文件的头文件extern声明这个变量,或者别的包含这个头文件的文件里extern声明这个变量,这样变量只是在源文件你定义一次,其他地方的都只是声明,调用的地址还是那个定义了的源文件里面开辟的------如:b.h,c.h都包含了a.h,这时候可以在a.cpp里面定义全局,在a.h文件extern下就行,这样b.h,c.h就都能用了,或者在b.h,c.h以及他们的源文件extern也可以。

对于static,const全局变量,则可以定义在头文件里,因为它们的连接性为内部,它们的地址只有在本文件里访问,即使这个头文件被其他的文件(.cpp或.h)包含,虽然重复定义,  c++ primer里讲的const变量定义时默认为文件的局部变量(内部连接性),当头文件中定义了const变量后每个包含该头文件的文件都有了自己的const变量。这与单一定义规则不矛盾,static也是同样,但是const的连接性可变,在const变量前面加上extern后,就变成全局变量,外部连接性,这时候要注意包含的问题。  而在.cpp文件里定义的const或者static变量,是不可以被别的文件访问的。(注意.h    .cpp等之间的包含关系)--------------------------------extern用于互不包含的文件里,或者被包含的文件。
包含意味着重新定义,但是对于互不包含的文件不可以定义同名的外部全局变量,外部全局变量属于外部连接性,这样就导致了重定义!当然加上static或者const就可以,这里有个全局存储区的区分------http://blog.csdn.net/u010177010/article/details/50737429,内部链接的变量地址所在的存储区跟外部链接所在的存储区是不同的,但是都属于全局存储区!

    对于static,const全局变量,如果在两个互不包含的文件里定义了相同的变量,第三个文件包含了这两个文件,就会出错,因为包含意味着重定义,同个内存块不可能有两个相同名字的内存。

总之,编译是否出错,看的是  变量的连接性以及是否重定义