復合型別與const關鍵字

2021-07-05 08:45:07 字數 3480 閱讀 4883

前面我們講了指標和引用的基本用法(指標用法)

(引用用法)  , 現在我們來看比較複雜的型別 -- 指標引用。(不存在引用指標)

這是復合型別 , 指標引用 , 顧名思義 , 指標引用就是對指標的引用。

int i = 0 , *pi = &i;

int *&rpi = pi; //這裡的指標引用應該這樣閱讀 (int *(&rpi)) , 即是rpi是引用 , 是對整形指標的引用

c++關鍵字中的const指的是英文中的constant , 即常量的意思 (下面的常量指const修飾的物件), 所以const 是用來修飾常量的關鍵字 , 下面來看看const是怎麼作用於內建變數的:

const int ci = 0;    //const放在類名前面 , 用0初始化ci

const int ci2 = ci; //用ci來初始化ci2

//ci++; 錯誤 , 常量不能改變

//const int ci3; 錯誤 , 常量必須初始化

常量除了不能改變自身和必須初始化外 , 跟一般變數一樣 , 另外 , 常量只在文字內有效。

對於類的常量物件 , 與基本型別的常量相似 , 不能改變自身且需要初始化(有預設建構函式就可以執行預設初始化) , const物件不能改變成員變數(物件) , 同時不能呼叫非const成員函式 , 否則編譯器會報錯。

const string cs = "hello";

size_t size = cs.size(); //正確 , string::size() 不會改變內建成員 , 所以被宣告為const

//該函式宣告為 size_type size() const; 起作用的是後面的const

cout << cs[0] << endl; //正確

//呼叫的是該函式的const版

//s[0] = 'h'; 錯誤 , 用乙個const物件呼叫乙個非const函式

const與引用組合 , 會變成一種很特別的引用 --- 常量引用 。 我們可以把非常量物件賦給常量引用 , 這樣的話就不能通過引用來修改物件的值 , 實際上這只是引用一廂情願的認為它代表的物件是常量 , 但我們依然可以通過直接修改物件來達到修改的目的。但反過來 , 不能用乙個非常量引用來引用常量 , 因為這樣就代表可以用引用來改變常量 , 編譯器是不允許這樣做的。

int i = 0;

const int & ri = i;

//ri = 5; //錯誤 , ri是常量

i = 5; //正確 , 這樣i就變成5了 , 當然ri也是5

const int j = 5;

//int & rj = j; 錯誤 , 不能用非常量引用表示乙個常量物件

對於常量引用 , 還有乙個非常令人難以理解的特徵 , 就是可以把右值賦給常量引用 :

const int &r = 10;

const int &r1 = r * 5;

const int &r2 = right_int(); //right_int()返回乙個區域性int

double d = 10.2;

const int &r3 = d; //r3的值為10

上述**全部都是正確並都能通過編譯 , 可能有什麼人會有疑問 , 為什麼能夠將沒有物件的右值或者臨時物件賦給常量引用 。c++允許為乙個常量引用賦予乙個右值 , 所以編譯器會在記憶體中另外分配一塊臨時區域來生成物件 , 再把常量引用繫結到這個物件身上 , 而右值就是用來初始化這個臨時物件的。

根據上述的特徵 , 我們可以這樣定義函式:

void print(const int & i)

print(5); //合法

int i = 0;

print(i) ; //合法 , 把乙個非常量賦給常量引用

print(i + 9); //合法

接下來我們來看指標與const的結合 , 這裡的const 有兩種 , 一種是加在類名前面 , 如 const typename *pt , 這是指指向常量的指標(不一定是常量 , 也是指標一廂情願這樣認為) , 這種指標不能改變指向的物件的內容 ,但可以改變指向的物件 。還有一種是加在類名後面 , 如 typename* const pt , 這是指常量指標 , 可以改變只想物件的內容 , 但不能改變指向的物件 。

int i = 0 , j = 0;

const int * pi = &i; //指向常量的指標(在指標層面是常量 , 實際不一定)

int * const pj = &j; //指標本身是常量

//(*pi)++; 在指標層面指向的是常量 , 不能改變其值

pi = &j; //可以改變指向物件

(*pj)++; //可以改變指向的物件的內容

//pj = &i; 不能改變指向物件

對於乙個常量 , 可以用乙個指向常量的指標來指向它 , 卻不能用常量指標來指向它 , 因為指向常量的指標不能對該常量進行改動 , 這符合了常量的規則 , 而常量指標是可以改變指向物件的 , 這就違背了常量的規則。

const int i = 1;

const int * pi1 = &i; //合法 , 不能改變i的值

//int * const pi2 = &i; 錯誤 , pi2理論上有能力改變i的值

const int * const pi3 = &i; //合法 , 既不改變物件也不改變指向

最後講一下const返回值的函式 , 對於乙個有返回值的函式而言 , 如果返回值是右值(即返回型別名無字尾 , 沒有&運算子修飾) , 則我們無法將這個函式放在賦值表示式的左邊 , 但如果返回值是乙個引用 , 因為它是個左值 , 所以可以直接在賦值表示式左邊使用函式 , 如果我們不想函式返回值被修改 , 則需要在類名前加上const修飾:

int f1(int &i)

int& f2(int &i)

const int& f3(int &i)

//示例**:

int i = 5;

//f1(i) = 10; 錯誤 ,返回值是右值 , 不能放在賦值語句左邊

f2(i) = 10; //正確 , 把i的值改為10

//f(3) = 10; 錯誤 , 返回值是乙個常量引用 , 不能修改它的值

總而言之 , 常量的意思就是不希望你修改它 , 但要記住一點 , 常量不全是在編譯階段就已經確定下來的值 , 很多事要到執行階段才能獲得的。而且 , 在我們說常量的時候 , 有可能指字面值常量 , 有可能指const修飾的常量 , 還有可能指常量表示式 。

const關鍵字與指標

1 const修飾指標的四種形式 a.const是關鍵字,在c語言中原來修飾變數,表示這個變數是常量。const int inum 10 和 int const inum 10 的效果是一樣的。b.const修飾指標有4種形式。區分清楚這4種即可全部理解const和指標。1 const int p ...

const關鍵字與指標

const關鍵字與指標 const修飾指標的4種形式 1 const.關鍵字,在c語言中用來修飾變數,表示這個變數是常量。2 const修飾指標有4種形式,區分清楚這4種即可全部理解const和指標。第一種 const int p 第二種 int const p 第三種 int const p 第四...

const 關鍵字與指標

一.入門 概念引入 定義乙個 int 型別的普通變數 val 假設它的值是 10。再定義乙個指向該變數的指標 val ptr 它儲存了 val 的位址。1 int val 10 2 int val ptr val 乙個 int 型別的變數儲存的是 int 型別的值,同理,乙個指向 int 型別的指標...