const、define 和 static 的區別

define、const

在 C++ 中,const 和 define 都可以用來定義常量。但是這二者之間有很大的區別:

  • define 的作用

    用 define 定義的常量是沒有 類型 的,編譯器只是把所定義的常量值和這個常量的名字聯繫起來,編譯器在編譯的過程中只是把 常量名替換成對應的常量值,所有用到的地方都拷貝替換。

  • const 作用

    使用 const 定義的常量是 有類型的,這個值存放在了 記憶體的靜態區域中。

具體來說,二者具有以下這些方面的區別:

  1. 是否能用指針
    用 define 定義的常量是不能用指針去指向該值的,因為只是簡單的替換

const 定義的常量是可以使用指針去指向這個值的地址的

  1. 是否能定義函數
    用 define 可以定義一些簡單的函數,但是 const 不行

  2. 編譯器處理

    define 預處理階段替換

    const 編譯階段替換

  3. 類型檢查

    define 不檢查類型

    const 檢查變數類型

  4. 記憶體空間

    define 定義的常量不佔用記憶體空間

    const 定義的常量佔用靜態區域的存儲空間,而且只佔用一個拷貝

  5. 其他

    在編譯的時候,編譯器通常不為const變數分配存儲空間,而是保存在了符號表中,可以節省記憶體,這使得它成為了編譯期間的常量,沒有了頻繁的讀寫記憶體的操作,效率很高

  6. 作用範圍

    define 宏定義的作用範圍僅在當前的文件中

    const 定義的作用範圍也僅僅在當前文件中,當不同的文件中出現了同名的 const 變數的時候,相當於定義了不同的變數,同時如果想在多個文件之間共享 const 變數,必須在變數定義之前添加 extern 關鍵字

    關於 const 的一些特性

    在C++ 中只使用 const 常量而不使用宏常量

  7. const 在類中的作用

如果想在類中共享一個常量,想當然的會使用 const 常量,但是這是不對的,因為 const 常量只在對象的生存期內是常量,但是對於整個類是可變的,因為一個類可以創建多個對象,不同的對象 const 成員的值可以不同。不能再類聲明中初始化 const 數據成員,const 成員變數的初始化只能在構造函數過程中

static

static 靜態變數的作用範圍只在一個文件內,程式開始的時候分配空間,程式結束的時候釋放空間,默認初始化的值為 0,使用過程中可以對 靜態變數的值進行修改,靜態變數和靜態函數只有本文件內的程式碼才能看見它,它的名字在其他文件中不可見。

  1. 在函數內部聲明 static 變數,static 變數可以當作對象間的一種通訊機制

如果一個局部變數被聲明為靜態變數,那麼將只有唯一的一個靜態分配的對象,它被用於在該函數的所有調用中表示這個變數。這個對象在第一次執行它所在的執行緒時到達它的定義時初始化。當同時編譯多個文件的時候,所有未加 static 的全局變數和函數都具有全局可見性,如果加了 static,那麼就會對其他文件隱藏

  1. 局部靜態對象

對於局部靜態對象,構造函數是在控制執行緒第一次通過該對象的定義時調用。在程式結束時,局部靜態對象的析構函數將按照他們被構造的相反順序逐一調用,沒有規定確切時間。存儲在靜態數據區的變數會在程式剛開始運行時就完成初始化,也是唯一的一次初始化。共有兩種變數存儲在靜態存儲區:全局變數和static變數,只不過和全局變數比起來,static可以控制變數的可見範圍,說到底static還是用來隱藏的

  1. 靜態成員和靜態成員函數

如果一個變數是類的一部分,但卻不是該類的各個對象的一部分,它就被成為是一個static靜態成員。一個static成員只有唯一的一份副本,而不像常規的非static成員那樣在每個對象里各有一份副本。同理,一個需要訪問類成員,而不需要針對特定對象去調用的函數,也被稱為一個static成員函數。類的靜態成員函數只能訪問類的靜態成員(變數或函數)。 static的第三個作用是默認初始化為0.其實全局變數也具備這一屬性,因為全局變數也存儲在靜態數據區.

Tags: