常量綜述(一)

 常量在C++裏面是一個很重要的概念,有很多細節的地方很容易忽略,這裏我根據《C++編程思想》總結了一下。

1.出現的歷史
        常量最普遍的用法是值替代,在C語言裏我們用宏來定義常量:
                    #define MAX  100
        但這是預編譯的,也就是說在編譯時只是簡單宏展開,並不檢查宏的語法是否正確。所以在C++裏引入了const來定義常量,增加了編譯時的檢查安全性得到了提高。(C99 裏面加入了const關鍵字)
                     const int size=100;
                     int array[size];
        size在編譯時就知道是多少了。常量通常是保存在符號表裏面的,沒有自己的內存地址,但我們可以強制編譯器爲常量分配內存
                     const int i=100;
                     long address=(long)&i;
        但要注意的是const可以用於集合,但必須保證編譯器不會複雜到把一個集合保存到它的符號表中,所以必須分配內存。在這種情況下,const意味着"不能改變的一塊存儲空間"。然而,不能在編譯期間使用它的值,因爲編譯器在編譯期間不需要知道存儲的內容。
                     const int i[]={1,2,3,4};
                     int f[i[3]];        //complie error
       還有C++中默認const是內部連接的,生存期爲這個程序的運行時間。

2.指針中常量
       指向const的指針:
                   const int* p;
                   int const *p;
             這兩種意義一樣都是說p指向的數是個常量,但p本身可以改變。
      const指針:
                   int* const p=&d;
             p指向的變量不一定是常量,但p本身不能再指向其它的變量。
             兩種可以一起使用          const int* const p=&d;      就都不能改變。
      要將const看成另外一種類型,轉換時要顯示轉換。
               const int e=2;
               int *w=(int*)&e;    //legal but bad practice

3.函數參數和返回值
                                 void f(const int i);
       這種函數就認爲在f裏面不會對 i 進行改變,調用時可以用常量,變量都行,但下面這種只能用變量做參數來調用
                                 void f(int i);
       返回const值
                 一般情況對於內部類型,我們都不會返回常量,但對於用戶定義的類型,按值返回常量就很重要了。如果一個函數按值返回一個類的對象爲const是,那麼這個函數的返回值不能是一個左值。

class X
{
         
int i;
   
public:
         X(
int ii=0)  { i=ii; }
        
void modify()   { i++; }
};

X f5()
{
     
return X();
}

const X f6()
{
      
return X();
}

void f7(X& x)
{
      x.modify();
}


int main()
{
        f5()
=X(1);
        f5().modify;         
//OK
        f7(f5());               //Cause warning
        f6()=X(1);           //compile error
        f6().modify();       //error
        f7(f6());               //error
}
 

      上面例子f6返回的是常量,是不能成爲左值的。

      但f5返回的不是常量也有問題,因爲返回值是個臨時量,編譯器使所有的臨時量自動地成爲const,這時編譯器必須產生一個臨時對象來保存f5的返回值,如果f7的參數是按值傳遞的話,它在f7中生成那個臨時量的副本,能很好的工作,然而f7是按引用傳遞的,這意味着它取臨時量的地址,又f7的參數不是按const引用傳遞的,可能會對參數進行修改,問題就是編譯器在計算表達式結束時,該臨時對象也會不復存在了,對臨時對象的任何修改也將丟失。其實第一行也有同樣的問題,可惜編譯器不會有提示信息。

發佈了26 篇原創文章 · 獲贊 1 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章