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; }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM