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()
{}

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

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

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

#define ASPECT_RATIO 1.653

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

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

class GamePlayer
{
    private:
    static const int NumTurns = 5;
};

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

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

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

Rational a,b,c;
(a*b) = c;

如果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;
}

可以這樣使用:

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

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

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