1. 程式人生 > >淺析C++中的const(比 define的優勢)

淺析C++中的const(比 define的優勢)

                     

使用const關鍵字來宣告變數,表明,記憶體被初始化後,程式便不能再對它進行修改。 const int Months = 12; 此時,應該注意的是應該在宣告中對const進行初始化,我們應該避免如下的寫法: const int Months; Months = 12;

你同樣可以使用const宣告一個指標和指標指向的內容: const char* const authorName = “Scott Meyers”;

下面兩種方式作用相同,只是看個人的習慣而已: void f1(const Widget* pw); void f2(Widget const * pw);

在C語言中,我們常常使用#define。那麼const相比於#define有什麼優勢

呢?

第一,const可以明確指定型別,而巨集定義沒有資料型別。 編譯器可以對const進行型別安全檢查,而巨集定義只是簡單的字元替換,有時候會產生意想不到的錯誤。

第二,可以使用C++的作用域規則將定義限制在特定的函式或是檔案中。 在預設的情況下,全域性變數的連結性為外部的,但const全域性變數的連結性為內部的。也就是說,在C++看來,全域性const定義就像使用了static說明符一樣。

const int fingers = 10;//和static const int fingers = 10;int main(){}
  • 1
  • 2
  • 3

但是在C++中可以使用extern關鍵字來覆蓋預設的內部連結性。 如 extern const int states = 50;

第三,const可以用於更復雜的型別。

第四,const更加方便除錯。 例如有如下定義:(Effective C++條款2:儘量以const替換#define)

#define ASPECT_RATIO 1.653
  • 1

但除錯程式有錯誤時,你可能會困惑,你也許無法看到ASPECT_RATIO,你會對1.653來自何處毫無概念。 第五,對於浮點常量而言,使用const會比使用#define更小量的程式碼。 因為預處器盲目的把ASPECT_TATIO替換為1.653,而導致目標碼中出現多分1.653.const不會出現該情況。

第六,無法使用#define建立一個class的專屬常量,而const可以做到。

class GamePlayer{    private:    static const int NumTurns = 5;};
  • 1
  • 2
  • 3
  • 4
  • 5

其實const最具有威懾力的用法是面對函式宣告時的應用。在一個函式宣告式內,const可以和函式返回值、各引數、函式自身產生關聯。 令函式返回一個常量值,往往可以降低因客戶錯誤而造成的意外。例如:

class Rational {...};const Rational operator* (const Rational& lhs, const Rational& rhs);
  • 1
  • 2

如果有客戶實現這樣的暴行:

Rational a,b,c;(a*b) = c;
  • 1
  • 2

如果a,b為內建型別,這樣的程式碼直截了當的不合法。而一個“良好的使用者自定義型別”的特徵是他們避免無端地與內建型別不相容。

const成員函式: 將const實施於成員函式的目的是為了確認該成員函式作用於const物件身上。 其中有一個很多人忽視的事實:兩個成員函式如果只是常量性不同,可以被過載。但是要注意該過載只是對應於成員函式,而不是非成員函式。

class TextBlock{public:    const char& operator[](std::size_t position) const    {return text[position];}    char& operator[](std::size_t position)    {return text[position];}private:    std::string text;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

可以這樣使用:

TextBlock tb("Hello");std::cout << tb[0];//呼叫char& operator[](std::size_t position)const TextBlock ctb("Kimi");std::cout << ctb[0];//呼叫const char& operator[](std::size_t position) const
  • 1
  • 2
  • 3
  • 4

上述使用了const的後置,即不會修改隱式訪問的物件。

按照函式過載的定義,函式名相同而形參表有本質不同的函式稱為過載。在類中,由於隱含的this形參的存在,const版本的 function函式使得作為形參的this指標的型別變為指向const物件的指標,而非const版本的使得作為形參的this指標就是正常版本的指 針。此處是發生過載的本質。過載函式在最佳匹配過程中,對於const物件呼叫的就選取const版本的成員函式,而普通的物件呼叫就選取非const版 本的成員函式。