C const 關鍵字總結

2022-08-21 23:21:14 字數 4406 閱讀 1691

c++ 中關於 const 的知識點很多,在這裡做個總結。

const 關鍵字修飾的變數在建立後值就不能改變了,因此必須在建立時進行初始化。

物件的型別決定了能夠在物件上進行哪些操作。對 const 物件來說,只能使用那些不能改變物件狀態的操作。

如果 const 物件是由乙個編譯時常量(compile-time constant)進行初始化的:

const

intbufsize

=512

;// input buffer size

那麼編譯器一般會在編譯時用這個常量替換該 const 變數。即編譯器把所有用到 bufsize 的地方替換為512。為了進行這種替換,顯然編譯器需要知道 const 變數的初值是多少,這就需要檢查 const 變數是如何被定義並初始化的。

如果程式分布在多個檔案中,為了對變數的值進行替換,編譯器在編譯每個用到該 const 變數的檔案時,都需要知道該 const 變數是如何被定義的,這就要求在每個用到該 const 變數的檔案中都對該變數進行定義(define 而不是 declare),然而乙個變數是不能被多次定義的。為解決這個矛盾,規定 const 變數的作用域是檔案本身(local to file)。當我們在多個檔案中定義名字相同的多個 const 變數時,就像在每個檔案中定義了乙個不同的變數一樣。

(對於一般變數來說只能在一處進行定義,在其他檔案中使用時需要使用 extern 關鍵字進行宣告。)

有時我們想在多個檔案中共享乙個 const 變數,但是該 const 變數的初始化器(initializer)並不是乙個常量表示式(constant expression,常量表示式的值在編譯時就可以被確定,如乙個數字或算術表示式,乙個通過 constant expression 進行初始化的 const 變數也是乙個 constant expression)。在這種情況下,我們不希望編譯器在每個用到該 const 變數的檔案中都單獨生成乙個新的變數。我們希望在乙個檔案中進行定義,在其他檔案中進行宣告。要達到這一目標,需要在定義和宣告時同時使用 extern 關鍵字(否則就是 local to file)。

// file_1.cc
extern

const

intbufsize

=fcn

();

// file_1.h
extern

const

intbufsize

;

下面用**具體演示一下。如果是 nonconst 的變數,則只能在一處進行定義。

// file_1.cc
#include
int

bufsize

=512

;

void

print

();

int

main

()

// file_2.cc
#include
int

bufsize

=100

;

int

print

()

編譯時報錯:multiple definition ofbufsize'。如果將兩個 bufsize 中的乙個改為 const,或兩個都改為 const,則編譯通過,輸出 100。

// file_1.cc
#include
const

intbufsize

=512

;

void

print

();

int

main

()

// file_2.cc
#include
extern

const

intbufsize

;

int

print

()

如果是這樣,file_1 中進行定義時沒有加 extern 關鍵字,則編譯時報錯:undefined reference tobufsize'

如果將兩個檔案中的 const 關鍵字都去掉,或者給 file_1 中的 const 變數也加上 extern 關鍵字,編譯成功,輸出512。

對 const 變數的引用

像普通變數一樣,也可以將乙個引用繫結到乙個 const 變數。對 const 變數的引用同樣不能改變該 const 變數的值。

const

intci

=1024

;

const

int&r1=

ci;r1=

42;// 錯誤,不能通過對 const 的引用改變 const 變數的值

int&r2

=ci;// 錯誤,不能用 nonconst reference 引用 const 變數

指標,const 和型別別名(type aliases)

考慮下面的**:

typedef

char

*pstring

;const

pstring

cstr=0

;const

pstring*ps

;

const 修飾的是 pstring,而 pstring 的型別是指向 char 的指標,所以 const pstring 是乙個 constant pointer to char,而非 pointer to const char。

不能通過直接替換來理解型別別名:

const

char

*cstr=0

;// 這是對 const pstring cstr 的錯誤理解

const 引數

進行賦值時,top-level const 會被忽略,所以以下兩個函式定義不能同時存在:

void

fcn(

const

inti

){}

void

fcn(

inti

){}

這兩個函式能夠接收同樣的引數,所以不算過載。

可以用 nonconst 物件對 low-level const 物件進行初始化,但不能用 low-level const 物件初始化 nonconst 物件。(low-level const 指標認為其指向的物件是 const 物件)。

inti=

42;

const

int*cp=

&i;// ok: cp 是 low-level const,可以用 nonconst 進行初始化,但不能通過 cp 改變 i 的值

const

int&r=

i;// ok: reference to const,不能通過 r 改變 i 的值

const

int&r2=

42;// ok

int*p

=cp;// error: 不能用 low-level const 初始化 nonconst,但可以用 const_cast 強制轉換

int&r3

=r;// error

int&r4

=42;// error: 不能通過 literal 初始化 plain 的 reference

如果可能就應該使用 reference to const

不用 reference to const,會讓呼叫者錯誤地認為函式會改變引數的值。而且不用 reference to const,會限制能夠傳遞的引數型別。不能向普通的 reference 傳遞 const 物件,不能傳遞 literal,不能傳遞需要轉換的型別。

const 成員函式

成員函式的引數列表後面可以加關鍵字 const,作用是修飾 this 指標。

this 指標預設是 const pointer to nonconst object,故不能指向 const object,也就是說 const 物件的方法無法被呼叫。將成員函式變為 const 成員函式,其 this 指標隱含引數變為 const pointer to const object。const 成員函式不能改變物件狀態。const 物件只能呼叫 const 成員函式。

注意 const 成員函式如果返回 *this,那麼返回的是乙個 const 物件,不能在返回物件基礎上繼續呼叫 nonconst 的成員函式。為解決這一點可以基於成員函式的 constness 對成員函式進行過載。

c const關鍵字 總結

在全域性作用於里定義非const變數時,在整個程式中都可以訪問.除非特別說明,在全域性作用於的宣告的const變數時定義該物件的檔案的區域性變數.死變數只存在與那個檔案中,不能被其他檔案訪問.非const變數預設為extern.要使const變數能夠在其他地方的檔案中訪問,必須顯示指定為extern...

c const關鍵字總結

const int max size 1024 這是最常見的用法,大家都沒問題,const在定義的時候需要初始化。有兩點需要注意一下 a const變數預設是區域性變數,如果需要全域性訪問,需要顯示地extern b const int max size 1024 與 define max size...

c const關鍵字詳解

正所謂酒足思淫慾,當衣食無憂的時候自然會產生很多的歪想法,就像當官一樣,權力越大,越容易腐敗。effective c 中第三條 盡量使用const。這就說明使用const是有很大的好處的,const就是把權力盡可能控制一下,這樣就會減免很多出bug的機會。因為乙個專案不可能只有乙個人開發,即使是乙個...