const 限定符 學(xué)習(xí)筆記 C++


const對(duì)普通變量進(jìn)行修飾,以表該變量在以后的使用中不被修改。

初始化

/*
*因?qū)ο笠坏﹦?chuàng)建后其值便不能被修改,所以必須進(jìn)行初始化
*根據(jù)初始化的值給定的表達(dá)式,初始化時(shí)機(jī)會(huì)再編譯時(shí)或運(yùn)行時(shí)確定
*當(dāng)編譯確定時(shí),會(huì)在調(diào)用其值的地方編譯時(shí)便用其值進(jìn)行替換  
*(類(lèi)似于define文本替換,但是define不會(huì)作類(lèi)型檢查)
*/
const int i = 12;                 //編譯時(shí)初始化
const int j = get_size();         //運(yùn)行時(shí)初始化

等價(jià)寫(xiě)法:
int const i = 12;
int const j = get_size();

const 對(duì)象作用域

默認(rèn)僅在當(dāng)前文本文件有效
需要在多個(gè)文件中生效時(shí),需要在其聲明和定義處用extern進(jìn)行修飾


xxx.cc
extern const int i = 123;
xxx.h
extern const int i;

const 引用及指針

引用 [1]
當(dāng)我們使用引用時(shí)一般都期望改變其值, 但是對(duì)于const對(duì)象本身是不被允許.
修改的,因此對(duì)于想把const對(duì)象綁定到引用時(shí)需要進(jìn)行const修飾, 以表該引用不會(huì)改變其值.

引用的類(lèi)型必須與其引用對(duì)象的類(lèi)型一致 [2], 但是在初始化常量引用時(shí)只要表達(dá)式的結(jié)果能轉(zhuǎn)換成引用的類(lèi)型即可。例如

double dval = 3.14;
const int &ri = dval;
原因是編譯器做了如下替換:
const int temp = dval;
const int &ri = temp;
// temp 是編譯器臨時(shí)創(chuàng)建的用于暫存表達(dá)式求值結(jié)果的臨時(shí)變量。

// 另const引用可以綁定在非const變量上
int i = 3;
const int &k_ri = i;
i = 5;        //此時(shí)k_ri == 5;

指針及頂層const和底層const
指針本身是個(gè)變量,那其也可被const修飾,用于表明該指針的值不會(huì)被改變。
由于指針指向的亦是一個(gè)變量,那么該變量也存在const修飾的可能性,即一個(gè)指針變量可能存在雙層const. 所謂低層const即用于修飾指針本身不會(huì)被改變,頂層const用于修飾指針指向的變量不會(huì)被改變。

int i = 1, b= 2;
const int *p = &i;  //底層const, *p解引用的值無(wú)法被改變, 但是p可以指向別的變量
*p = 4;   //不合法
p = &b;   //合法
int *const p2 = &i; //頂層const, p2無(wú)法指向其它變量,但是*p解引用的值可以改變.
*p2 = 1;  //合法
p2 = &b;  //不合法

注意:
進(jìn)行對(duì)象拷貝時(shí),對(duì)象必須有相同的底層const, 而頂層const則不影響.

const 在類(lèi)中的使用

class Foo {
public:
    ...
    int get_i() { ++z_; return i_;}
    int get_z() { return z_; };
    ...
private:
    int i_;  //隨意...
    int z_;  //計(jì)數(shù)get_i() 被調(diào)用的次數(shù);
}

//對(duì)于Foo這樣的類(lèi),如果某一天我們頭腦發(fā)熱想要聲明一個(gè)常量,并調(diào)用相關(guān)成員,如下
const Foo k_var;
k_var.get_i();        //調(diào)用出錯(cuò)
k_var.get_z();       //調(diào)用出錯(cuò)
//對(duì)于成員函數(shù)的調(diào)用會(huì)提示報(bào)錯(cuò),因?yàn)檫@些函數(shù)的調(diào)用可能會(huì)改變內(nèi)部成員變量的值,
//這與你的期望不匹配。因此我們必須聲明一個(gè)可被常量調(diào)用的版本, 通常如下,

class Foo {
public:
    ...
    int get_i() { ++z_; return i_;}
    int get_i() const { ++z_; return i_;}    //常量版本
    int get_z() { return z_; };
    int get_z() const { return z_; };          //常量版本
    ...
}

k_var.get_i();        //調(diào)用出錯(cuò)
k_var.get_z();       //正確
//此時(shí)對(duì)get_z()的調(diào)用是正確的,但是get_i()仍然是錯(cuò)誤的,
//因?yàn)樗噲D在const成員函數(shù)里面改變成員變量的值z(mì)_,
//成員函數(shù)一旦被const修飾,通常意味著this指針的形態(tài)在其內(nèi)部是const *this(便于理解),
//那么++this->z_這樣的操作肯定是不合法的。
//但是對(duì)于z_這樣我們希望無(wú)論在常量或非常量中都希望能夠改變的值,我們可以在聲明前加mutable修飾,表明是個(gè)可變的數(shù)據(jù)

class Foo {
public:
    ...
    int get_i() { ++z_; return i_;}
    int get_i() const { ++z_; return i_;}    //常量版本
    int get_z() { return z_; };
    int get_z() const { return z_; };          //常量版本
    ...
private:
    int i_;  //隨意...
    mutable int z_;  //計(jì)數(shù)get_i() 被調(diào)用的次數(shù);
}

k_var.get_i();   //正確

  1. 實(shí)際上引用的底層實(shí)現(xiàn)即是指針. ?

  2. C++ primer 2.4.1. ?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容