[c&cpp] c與cpp中的const關鍵字總結

來源:互聯網
上載者:User

      C++中用const限定符來定義常量,但const出現的可以出現在常量定義中,也可以出現在方法定義中,並且出現的位置也有所不同,所表示的意思也不同。

      在任何可能的情況下都要使用 const。在聲明的變數或參數前加上關鍵字 const 用於指明變數值不可被篡改 (如 const int foo ). 為類中的函數加上 const 限定符表明該函數不會修改類成員變數的狀態 (如 class Foo { int Bar(char c) const; };).
      但是,const 是入侵性的: 如果你向一個函數傳入 const 變數, 函數原型聲明中也必須對應 const 參數 (否則變數需要 const_cast 類型轉換), 在調用庫函數時顯得尤其麻煩。關鍵字 mutable 可以使用, 但是在多線程中是不安全的, 使用時首先要考慮安全執行緒.

const 的位置:
      有人喜歡 int const *foo 形式, 不喜歡 const int* foo, 他們認為前者更一致因此可讀性也更好: 遵循了 const 總位於其描述的對象之後的原則。但是一致性原則不適用於此, “不要過度使用” 的聲明可以取消大部分你原本想保持的一致性. 將 const 放在前面才更易讀, 因為在自然語言中形容詞 (const) 是在名詞 (int) 之前.不強制 const 在前. 但要保持代碼的一致性!

1. 定義 const 對象
    因為常量在定義後就不能被修改,所以定義時必須初始化:

    const int bufSize = 512; // ok: initialize

2 . C與C++中const的區別
    c++中,const 對象預設為檔案的局部變數,也就是在C++中const變數的連結性質是內部的,對於C++來說,const 變數是global namespace的全域變數,C++預設const變數的連結性質是內部的,而C中const變數的連結性質是外部的. 在C++中,const變數預設是內部連結的,除非你顯式加上extern修飾詞,否則,其它檔案是看不到的。

    // file_1.cc 
    // defines and initializes a const that is accessible to other 
    // files 
    extern const int bufSize = fcn(); 
    // file_2.cc 
    extern const int bufSize; // uses bufSize from file_1 
    // uses bufSize defined in file_1 
    for (int index = 0; index != bufSize; ++index) 

3.  指標和 const 限定符

1)指向 const 對象的指標

      允許把非 const 對象的地址賦給指向 const 對象的指標,不允許把一個 const對象的地址賦給一個普通的、非 const 對象的指標。

     const double pi = 3.14; 
     double *ptr = π              // const對象的地址不能賦給非const指標 
     const double *cptr = π    // ok: cptr is a pointer to const 
     const void *cpv = π        // ok: cpv is const 
     double dval = 3.14; 
     cptr = &dval;  // ok: but can't change dval through cptr 

      可以通過賦值改變指標本身的值,但不能通過指標(eg:*p)改變指標指向的值。

     char * str = (char*)malloc(sizeof(char)*10); 
     strcpy(str,"abcd"); 
     const char* cpstr = str;// OK: cpstr = "abcd" 
     strcpy(str,"dcba");  // ok: cpstr = "dcba" 
     //strcpy(cpstr,"ddd"); //error 
     *cptr = 10.12; //Error 

    2)指向 const 對象的 const 指標 
       const 指標——本身的值不能修改, 但可以改變指標指向的值:

     int errNumb = 0; 
     int *const curErr = &errNumb; // curErr is a constant pointer 
     *curErr = 10; //OK 

    3)指向 const 對象的 const 指標

     const double pi = 3.14159; 
     const double *const pi_ptr = π 
     // pi_ptr is const and points to a const object 

    4)區別指向 const 對象的指標和const 指標

         一個很好的方式就是,從定義的右邊往左邊讀其意思來區別。比如const double *ptr 可 以讀為ptr指標指向一個const double對象,

         這樣就知道是指向const對象的指標了;同樣,int *const curErr 可以讀為 curErr 是一個const型的指標,指向int對象。

    5)指標和 typedef

         先看下下面的代碼,cstr1、cstr2、cstr3那些是const指標,那些是指向const對象的指標?

      string s ; 
      typedef string *pstring; 
      const pstring cstr1 = &s; //const修飾的是pstring 
      pstring const cstr2 = &s; //const修飾的是pstring 
      string *const cstr3 = &s; 

        可能有人會誤認為cstr1是指向const對象的指標,其實cstr1、cstr2、cstr3都是const指標。錯誤的原因在於將 typedef 當做文本擴充了。聲明 const pstring 時,

        const 修飾的是pstring的類型,這是一個指標。該聲明語句應該是把 cstr1 定義為指向 string 類型對象的 const 指標,這個定義等價於cstr3的聲明定義。

4.  const 形參

      在調用函數時,如果該函數使用非引用的非 const 形參,則既可給該函數傳遞 const 實參也可傳遞非 const 的實參。即可用 const 對象初始化非 const 對象,反之亦然。如果將形參定義為非引用的 const 類型,則在函數中,不可以改變實參的局部副本。由於實參仍然是以副本的形式傳遞,因此傳遞給 fcn 的既可以是 const 對象也可以是非 const 對象。如果使用引用形參的唯一目的是避免複製實參,則應將形參定義為 const 引用。

      // compare the length of two strings 
      bool isShorter(const string &s1, const string &s2){ 
         return s1.size() < s2.size(); 
        } 

注意:調用非 const 引用形參的函數時,傳遞一個右值或具有需要轉換的類型的對象同樣是不允許的:

    int incr(int &val) { 
         return ++val; 
    } 
    int main() { 
             short v1 = 0; 
             const int v2 = 42; 
             int v3 = 11 
             v3 = incr(v1); // error: v1 is not an int 
             v3 = incr(v2); // error: v2 is const 
             v3 = incr(0); // error: literals are not lvalues error C2664: cannot convert parameter 3 from 'int' to 'int &' 
             v3 = incr(v1 + v2);  // error: addition doesn't yield an lvalue 
             int v4 = incr(v3);   // ok: v3 is a non const object type int 
        }  

    問題的關鍵是非 const 引用形參只能與完全同類型的非 const 對象關聯。

    總之,應該將不需要修改的引用形參定義為 const 引用。普通的非 const 引用形參在使用時不太靈活。這樣的形參既不能用 const 對象初始化,

    也不能用字面值或產生右值的運算式實參初始化。

5. const 對象

    指向 const 對象的指標或引用只能用於調用其 const 成員函數,如果嘗試用它們來調用非 const 成員函數,則是錯誤的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.