C++: 全局变量和static变量初始化问题

1. 初始化时机

全局变量、文件域中的静态变量、类中的成员静态变量在main函数执行前初始化;局部变量中的静态变量在第一次调用时初始化。

C和C++的区别:局部静态变量:

在C语言中是编译期初始化并分配内存,故不能用变量给静态局部变量赋值,只能用常量。

在C++中是第一次执行时初始化,因为C++引入了对象的概念,对象一般需要构造函数,无法简单的分配内存,故可以用变量赋值,并且在第一次使用时初始化。

 

初始化又分为静态和动态:

 

静态初始化:

  针对用常量来对全局变量进行初始化的情况,这个变量是简单的内置类型(不包括含构造函数的复杂类,归属于下一项)。例如这里的a变量。

int a = 3;

class A{
};

  在程序加载过程中完成。

  根据变量是否设置初值分别放于data segment段(设置初值)和bss段(未设置初值)  

 

动态初始化(运行期)(main函数前,局部静态变量除外):

  1. 需要经过函数调用来完成的初始化。例如这里的a变量。

int a = foo()

  2. 复杂类型的初始化。需要调用构造函数。例如这里的aa变量。

Class A{
    A(){}
}

A aa;

 

静态初始化的时机是先于动态初始化的。

 

 1)类的静态成员变量声明和定义

使用过类中的静态成员变量的伙伴都发现了,在类中定义的静态成员变量,还必须要在类外定义下才可以使用,否则会编译报错。

那么为什么会出现这种情况呢?

静态成员变量不属于任何一个对象,对象的数据中不应该包含静态成员的数据。所以在定义类的时候不会给静态变量分配内存只是声明,因此就要在其他地方分配即定义。

定义与声明的区别:

声明:只是向程序表面变量的类型和名字。

定义:为变量分配内存,也可以顺便初始化。程序中变量有且只有一个定义(更能说明为什么要在类外再定义下类的静态成员变量了)。

 

2. 初始化顺序

对于编译单元(同一个文件)的全局变量来讲,初始化顺序跟声明的顺序一致。销毁顺序则相反。

对于不同编译单元的全局变量,初始化顺序不确定。对于不同编译单元的全局变量互相引用的情况应避免。

 

3. 解决不同文件相互引用全局变量初始化顺序不确定问题

  1)可以通过函数调用,引用的时候不直接引用全局变量,而是放在一个函数中。函数中的全局变量在调用时初始化。

int get_a() 
{ 
  static int a = 5;
  return a; } int get_b() {
  static int b = get_a();
  return b; }

 

posted @ 2021-02-19 23:09  Dylan_Liang  阅读(9928)  评论(0编辑  收藏  举报