到目前為止,我們大多處理的是數字和字串。 為了模擬真實世界,我們可能會希望變數只能取有限幾個值。 你可能會想要一個專屬的型別,裡面有幾個不同且各有名稱的值。 舉例來說,在滑板工廠裡,板身的材質只能是楓木、竹子或塑膠這幾種選擇。
你可以用整數來編碼這些值,但這樣就得額外寫程式碼,檢查系統傳來的材質是不是無效值。
那些魔術數字的意義難以在原始碼中追溯,而且很容易混淆。
enumerations可以用來鼓勵寫出更具表達力的程式碼,也能避免不小心比較錯誤。
這種列舉的特定名稱叫做scoped enumeration。
下面的程式碼片段示範如何撰寫DeckMaterial enumeration。
請注意enum class關鍵字,以及定義結尾的;:
enum class DeckMaterial {
maple,
bamboo,
plastic
};
現在,看看滑板店裡的定價函式,並留意用來指定enumeration中enumerator的作用域解析運算子(::):
double deck_price(double base_price, DeckMaterial material) {
if(material == DeckMaterial::plastic) {
return base_price * 0.9;
}
return base_price * 1.3;
}
想像一下,你有第二個enumeration代表輪子材質:
enum class WheelMaterial {
steel,
clay,
plastic
};
雖然輪子和板身都可以用_塑膠_製作,但兩者不會被搞混。
它們是不同的_型別_:DeckMaterial的 plastic 和 WheelMaterial的 plastic。
每個enumeration的enumerators都會落在自己的作用域裡,也就是自己的namespace。
這就是它們被稱為scoped enumerations的原因。
你可能會想,名稱既然叫做scoped,那應該也有_unscoped_列舉吧,你猜對了。
Unscoped enumerations越來越不受歡迎,因為它們全都共用同一個全域命名空間。
因為共用的關係,你無法有兩個unscoped enumerations擁有相同的enumerators,就像上面範例中的_plastic_一樣。
此外,unscoped enumerations會隱式轉換成整數。
看看下面的範例,結果會出乎意料:
enum CitrusFruits {
lemons, // 0
oranges, //1
};
enum IceCream {
walnut, // 0
apples, // 1
};
bool comparison{apples == oranges};
// => true
// Example from above:
bool comparison{DeckMaterial::plastic == WheelMaterial::plastic};
// => Does not compile!
如果你想將scoped enumerations轉換成整數,可以使用static_cast<int>。