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 對象實例的,但對象實例區並不包含靜態成員變量,也就是說,改變靜態成員變量也是合法的。 |