天天看點

const 關鍵字

文章目錄

      • 1. const 的設定
      • 2. const 的引用
      • 3. const 和指針
        • 3.1 常量指針
        • 3.2 指針常量
      • 4. 頂層 const 和 底層 const
      • 5. constexpr 和 常量表達式
      • 6. const 修飾成員函數

1. const 的設定

  • const關鍵字修飾變量時,限制該變量的值不能夠被改變

    。 由于const關鍵字修飾的變量的值不能夠改變,是以

    const對象必須初始化

  • 相較同一類型的非常量變量,

    常量變量隻能執行不改變其内容的操作

    ,如算術運算、拷貝初始化等;
  • 預設情況下,const對象被設定為僅在檔案内有效

    ;若是需要隻在一個檔案中定義const,而在多個檔案中聲明并使用,則在const變量的定義和聲明前都添加extern關鍵字;

2. const 的引用

  • 引用不是對象

    ,是以對于引用和const一起出現的情況,隻能是引用常量對象,也即對常量的引用;
  • 把引用綁定到常量對象上,稱之為

    對常量的引用(reference to const)

    ,簡稱

    常量引用

  • 引用的類型必須與多引用對象的類型一緻,但有兩種例外情況:

    初始化常量引用時允許用任意表達式作為初始值

    ,隻要該表達式結果能夠轉換成引用的類型;

    常量引用可能引用的是同一類型的非常量對象

    ,可以了解為引用“自以為是”的覺得自己指向了常量,自覺不允許改變所指對象的值;

3. const 和指針

3.1 常量指針

  • 類似于常量引用,也可以将指針指向一個常量變量,也就是

    指向常量的指針(pointer to const)

    ,又稱

    常量指針

    ,其不能用于改變其所指向對象的值;
  • 若想存放常量對象的位址,隻能使用指向常量的指針/常量指針;
  • 和常量引用一個道理,常量指針/指向常量的指針也不強制規定所指對象必須是一個常量;

3.2 指針常量

  • 指針是對象

    ,是以可以把指針本身定義為常量,遵循在1中所提到的,

    指針常量(const pointer)

    必須初始化。定義方式為

    type * const var

  • 指針常量表示不變的是指針本身而不是指向的值,是以并不意味着不能通過指針常量修改所指對象的值;

4. 頂層 const 和 底層 const

  • 指針本身是一個對象,其又可以指向一個對象,是以指針本身是不是常量以及指針所指的對象是不是常量是兩個互相獨立的問題;
  • 頂層const (top-level const):表示指針本身是個常量

    。其可表示任意的對象是常量,适用于任何資料類型;
  • 底層const (low-level const):表示指針所指對象是個常量

    。其與指針、引用等複合類型的基本類型部分有關,其中

    用于聲明引用的const都是底層const

  • 當執行對象的拷貝操作時

    ,頂層const不受什麼影響,然而

    拷入和拷出的對象必須具有相同的底層const,或兩對象的資料類型能夠互相轉換

    (非常量可以轉換成常量);

5. constexpr 和 常量表達式

  • 常量表達式(const expression)

    指值不會改變并在編譯過程中就能得到計算結果的表達式。顯然,字面值時常量表達式,一般來說函數做右值,函數傳回的具體值直到運作時才知道,不是常量表達式;
  • 為了友善分辨一個初始值到底是不是常量表達式,在C++11版本中引入了新關鍵字

    constexpr

    。允許将變量聲明為constexpr類型以便由編譯器驗證變量是否是一常量表達式;
  • C++11 新标準允許定義一種特殊的constexpr類型的函數,足夠簡單到編譯時就可以計算出傳回值,以便用函數初始化constexpr類型變量;
  • 聲明為constexpr的變量一定是一個常量,且必須用常量表達式初始化;
  • constexpr指針的初始值必須為nullptr或0,或是存儲于某個固定位址中的對象。在constexpr聲明中如果定義了一個指針,constexpr隻對指針有效,與指針所指對象無關;
const int *p = nullptr; //p是一個指向整型常量的指針
constexpr int *q = nullptr; //q是一個指向整數的常量指針
           

以上講解了const關鍵字的文法、含義和引申出的相關概念,對于const關鍵字的應用推薦檢視:

①關于C++ const 的全面總結

②關于const 作用和用法 C++ const 的全面總結

下表列出了const的應用場景:

const 關鍵字

6. const 修飾成員函數

就如上表中的No.5的作用所說,const也可修飾成員函數,表示該成員函數具有常量性。具體的作用和應用場景見下圖所示:

const 關鍵字

以 std::basic_string 的 operator[] 運算符的重載(函數簽名不同)為例,可以更好的了解到,對于一個(非)常量對象其與相關的(非)常量成員函數之間的使用的關系和邏輯。

有關圖檔中的COW機制,見:标準C++類string的Copy-On-Write技術 和 COPY-ON-WRITE 原理。

簡單來說,在複制一個對象時并不是真的在記憶體中把原來對象的資料複制一份到另外一個位址,而是在新對象的記憶體映射表中指向同原對象相同的位置,并且把那塊 記憶體的 Copy-On-Write 位設為 1。在對這個對象執行讀操作的時候,記憶體資料沒有變動,直接執行就可以。在寫的時候,才真正将原始對象複制一份到新的位址,修改新對象的記憶體映射表到這個 新的位置,然後往這裡寫。

簡介

通俗的稱為寫時拷貝的一種機制,也就是說讀的時候并不需要拷貝

應用場景

并發線程中對同一塊資源同時處理資料錯亂問題

一般解決方法

1.對同時通路的這塊資源加鎖,多個線程輪流通路;

2.對每個來讀這塊資源的線程直接通路就是了,每個來寫這塊資源的線程就臨時拷貝一份資源給他們處理,也就是copy on write。

繼續閱讀