天天看點

C++ 常量定義之我見

到目前為止,C++的常量定義我所知道的有這麼幾種:

1. #define

2. const 

3. enum

下面作一些個人總結:

1. #define CONST_VALUE value

幾乎沒有人推薦用的形式。

主要有下面三個問題:

a. 類型檢查問題:

在我看來這個是最為人诟病的問題,因為宏替換發生在預處理階段,是以編譯器不會去檢查該常量的類型,進而避免可能的錯誤。

當然很多時候,這個缺點并不會導緻緻命的錯誤,尤其是如#define SIZE 100 這樣人畜無害的語句。

相對應的,如果是#define SPEED 1.02,那麼在接下來int i = SPEED時,編譯器可能不會報錯,是以會導緻不可預測的問題。

從這個角度上來講,#define是有明顯不足的。

b. 作用域問題:

宏定義是全局的,沒有作用域的概念。

就是說,如果我再test.h 裡面定義了#define SIZE 100,那麼任何包含這個頭檔案的cpp檔案都不可以對SIZE有别的解釋。

這就限制了宏定義常量一般不能放在頭檔案中,因為這将導緻所有包含這個頭檔案的cpp檔案的名字空間都被污染。

(而這個問題在const typename CONST_VALUE = value的形式中可以由名字空間的引入而得到解決)

如果把常量的定義放在cpp檔案的頭部,那麼該常量的作用範圍就被限制在檔案内,那麼這個問題所帶來的困擾會小得多,除非你希望一個cpp檔案裡的不同部分對于同一個變量名可以有不同的解釋。

然而,在一些情況中,必須将常量定義放在頭檔案中,包括:

你希望幾個cpp檔案公用的常量。

你希望在頭檔案中使用常量。比如數組大小的定義,自定義類的類内定義函數的實作部分。

c. 編譯後的檔案大小和運作速度問題:

有的文章會寫到由于#define 和const 的機制不同,它們的運作效率和生成的object檔案大小會 存在差異。編譯原理和彙編學的都不好,我覺得這裡我沒有發言權。唯一想說的是,跟前面兩個問題比起來,我覺得這個問題是小巫見大巫。有興趣刨根問底的同學可以自行查找資料~

2. const 

我覺得這應該是c++裡面最讓人頭疼的關鍵字了。沒有之一。

因為它含義太多,是以顯得撲朔迷離。這篇文章中僅僅讨論作為常量修飾符的作用。

const 的出現可以适用于所有c++的常量定義場合,配合namespace關鍵字,很好的解決了類型檢查和作用域的問題。

此外const 還可以用來定義常量數組。是以我認為它是c++的官方常量定義法。

如果const 放在類定義的private中,以static const 修飾,可以成為類内專用的常量。

小插曲1: vs支援在頭檔案中定義常量,而出于封裝的考慮,可以把常量定義放在實作檔案中。

小插曲2: vs不允許浮點類型的靜态常量成員函數在類中初始化。

3. enum

這個關鍵詞定義常量我認為屬于旁門左道,但有些人指出它更簡潔。

其實我非常懷疑vs的類内定義整型靜态成員常量的實作方式和enum是共用的。

果真如此,那麼兩個的差别可以說僅僅在static const 要多打幾個字。

有的資料還說枚舉常量不會占用對象的存儲空間,它們在編譯時被全部求值。

上面這句話是抄的,我沒大看得懂。還請各路大神指點。不過看來enum還是有些别的可取之處的。

當然,限制是非常明顯的。隻能是int型。

繼續閱讀