c c 學習總結(4) const關鍵字

2021-08-20 21:34:07 字數 2496 閱讀 7291

const這個關鍵字在c++被「過載」了很多次,寫在不同地方表示不同的意思。需要分別來說明:

第一點:const修飾的變數一定要初始化,const變數的值在編譯時就要被確定,放在「**段」的「.rodata」中,如果在程式中顯示的修改const變數,會報編譯時錯誤,如果一些技巧來欺騙編譯器來修改const變數,其行為是未定義的。例如:

int num = 90;               //定義非const變數

const int &r = num; //使用const引用來指向num,此後就不能通過r來修改num了

const_cast(r) = 100; //使用rtti來去掉r的底層const,然後再來修改r,這樣做是安全的因為num本來就是非const

cout<(r) = 100; //使用rtti來去掉r的底層const,然後再來修改r,這樣做行為是未定義的

cout《第二點:const變數的連線性是內部的。在標頭檔案中定義乙個非const變數(如 int num = 10;),由於標頭檔案可能會被多個實現檔案包含,這個「num」變數是乙個全域性變數,它是乙個強符號,鏈結器會報重複定義,有趣的是被const修飾的變數卻不會,原因是const變數的連線性是內部的,它的作用域和static一樣會被限制在當前翻譯單元中,這種連線性為內部的變數,在編譯時就被初始化了,不需要等到執行時(const變數的初始化可以被推遲到執行時,後面介紹)。

const在修飾指標變數和引用時會有頂層底層之分,看**

int num = 90;

int * const p = &num; //此時的p是帶有頂層const的,它表示p是乙個常量,因此必須初始化

int const * p = &num; //此時的p是帶有底層const的,它表示不能通過p來修改num,而不管num本身是否為常量。

const int * p = &num; //這種寫法等價於上面的

int num = 90;

int const & r = num; //此時的p是帶有底層const的,它表示不能通過p來修改num,而不管num本身是否為常量。

const int & r = num; //這種寫法等價於上面的

int & const r = num; //錯誤,沒有這種寫法

//關於為什麼沒有上述寫法,我的理解是引用的本質是乙個「自解引用的常量指標」,如

int &r = a; //等價於 int *const r = &a; 這也是為什麼引用必須初始化的原因

cout《第一點:先說說什麼是常量表示式:常量表示式是在編譯時就能確定其值且在執行時不會改變的量,乙個變數是不是常量表示式由其變數型別和初始值決定。

int num = 1;//不是

const int num = 1;//是

const int num = size();//不是,const修飾的變數可以在編譯時初始化,也可以推遲到執行時

第二點:c++11引入了constexpr,被constexpr修飾的變數或函式必須在編譯時計算出來,看**

constexpr int num = size();        //size()必須為constexpr函式

//constexpr函式是乙個隱式inline函式,還要求該函式的引數和返回值只能是字面值,不能是虛函式,不能是遞迴函式

第三點:constexpr與指標

cosntexpr int * p = #        //constexpr是頂層的

int * const p = # //等價於上面的

constexpr const int * p = #

const int * const p = # //等價於上面的

頂層const不能構成過載的依據,但底層const可以構成過載的依據,例如

void show(int num);

void show(const int num); //頂層const,這兩個不是過載

void show(int * p);

void show(int *const p); //頂層const,這兩個不是過載

void show(int & r);

void show(const int &r); //底層const,是過載

void show(int *p);

void show(const int *p); //底層const,是過載

//另外

void show();

void show()const; //可以過載

當我們在類中宣告const成員變數時,變數一定要初始化。我們需要在類的建構函式的初始化列表中初始化,不能在函式體中初始化(因為函式體是在對變數賦值,而不是賦值)。還需要注意的是:由於通過建構函式可以把該變數初始化成不同的值,使得不同物件之間的值不同(這可能不是我們所想的),所以可以採用匿名enum型別定義常量。

C C 中 const 關鍵字用法總結

首先,來看看const的基本含義。在 c c 語言中,const關鍵字是一種修飾符。所謂 修飾符 就是在編譯器進行編譯的過程中,給編譯器一些 要求 或 提示 但修飾符本身,並不產生任何實際 就 const 修飾符而言,它用來告訴編譯器,被修飾的這些東西,具有唯讀的特點。在編譯的過程中,一旦我們的 試...

C C 中const關鍵字

const經常被用到,所以今天總結一下const關鍵字的用法,常用的場景為修飾變數 c c 不同 修飾指標和引用,修飾函式引數,修飾函式返回值,修飾函式定義體 類 成員函式 1 修飾變數 cosnt在修飾變數時,在c和c 中是不同的。const int a 5 intarray a 在c語言中是錯誤...

const關鍵字總結

這裡會呼叫string類的預設建構函式初始化陣列元素。const int cur 這裡的cur是乙個指向int型別的const物件的指標,const先頂了cur指向的物件的型別,而並非cur本身,所以cur不是const的 const double cur const double pur 1.2 ...