C++ const 指針

const在面試的時候考得多,特地小結一下。

1,const是修飾符,它表示某個對象是常量,即不能修改,而C++沒能徹底拋棄指針這個C留下的遺產而有些尷尬,指針是比較圓滑的傢伙,它有雙重身份,有時表示它自己,有時表示它所指的對象(所以C++建議我們儘量用引用而不是指針)

const double e;// error

const double pi=3.14;// ok,需要初始化

這樣的用法沒什麼好說的。

2,指針帶來的問題

像這樣寫:

int a,b;

const int *p=&a;

實際上沒有定義一個常量指針,而是指向常量對象的指針,這意味着後面可以這樣

p=&b;//ok

a,b不是常量而是變量,這是可以的,事實上編譯器不管這個,而是管*p和p->這樣的運算不能被修改

*p=1;//error

就是說上面那句定義的並不是一個常量,它相當於

int const *p;

實際上是個變量。

而真正的常量指針怎麼寫?這樣

int * const p=&a;//ok

int *const p;// error

它的意思是p不能再改,只能賦值一次,這實際上是什麼,是引用。引用和指針有着這樣一個巨大的差異。

上面ok的代碼,實際上可以寫成

int &p=a;

也就是說根本不需要常量指針,因爲有引用(?)

3,引用和const

引用有着針指的優點,但是它的身份是確定的,不像指針有雙重身份,所以用const修飾沒什麼問題。

const int &p=a;

它的意思實際上和這樣寫差不多

int const * const p=&a;

本身一次賦值,所指對象也不能改。這就是喜歡考的那個所謂,一個指向一個常量對象的常量指針。

試一下這麼寫

int const & const p=&a;

多此一舉,在VC上會給出個警告,因爲在語義上是重複的。

 

 

 

const 指針:

const 這個關鍵字可以用在:

類型前: 指明類型是常數,即所指向的值是常數,值不可改變。

變量前: 指明變量是常數,即指針本身是常數,指針本身不能改變。

const int *p1;   //the int pointed to is constant

int * const p2; //p2 is constant, it can't point to anything else.

或者上面兩者的結合

const int * const p3; //指針本身和指向的內容都不可以改變。

■聲明成員函數爲 const 時,編譯器把函數內改變對象實例數據的任何企圖都視爲錯誤。

■如果程序聲明指向 const 對象的指針,該指針只能調用 const 函數成員。

下面舉例說明:

class MyClass

{

private:

int FValue;

public:

void SetValue(int n) { FValue = n; }

//定義 const 成員函數

int GetValue() const { return FValue; }

};

void main()

{

//定義指向 const 對象的指針

const MyClass * pConstMyClass = new MyClass;

//pConstMyClass->SetValue(100); //非法,不可以改變內容。

pConstMyClass->GetValue();

}

好神奇哦,其中原因就是 const this 指針。

        當程序聲明對象爲 const 時( 見 main() 中定義的 const MyClass ... 那一行 ), 實際上等於編譯器生成要調用的成員函數的 this 指針參數爲 const MyClass * this 這種形式, 呵呵,這樣 this->FValue = n; 顯然非法。所以,指向 const 對象的指針只能調用 const 成員函數。即:

this 指針爲:

const class MyClass //定義爲 const 時

class MyClass &      //非 const 時

        當進行類型轉換時, class MyClass & 轉成 const class MyClass 是可以的,反過來就不行,因此,普通的對象實例可以操作任何成員函數,而不管成員函數有沒有 const。

        這裏要說明一點的是靜態成員變量。還記得嗎?以前說過,靜態成員變量不屬於對象實例,只屬於類。也就是說編譯器要操作靜態成員變量,對於非靜態成員函數來說是不能用 this 指針去操作它的,因爲靜態成員變量不在對象實例區,這樣一來,即使非靜態成員函數聲明爲 const,還是可以改變靜態成員變量的。像本例中 pConstMyClass 是指向 const 對象實例的,但對象實例區並不包含靜態成員變量,也就是說,改變靜態成員變量也是合法的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章