1. 型別檢查 (type-safe),這是#define, const做不到的。
2. 將相關的type放在別一個enums,不會像#define, const 定義的常數一樣,沒有group的概念。
enum Style
{
StyleA,
StyleB,
StyleC,
}
enum Area
{
Area1,
Area2,
Area3,
Area4,
}
// pass
Style s1 = StyleA;
// error, can't convert from int to enums 'Style'
s1 = 2;
// error, can't convert from enums 'Area' to 'Sytle'
s1 = Area3;
// pass, if you really need do it (it's non type-safe)
s1 = (Style)10;
s1 = (Sytle)Area4;
// ok, but it's non type-safe
int s2 = Area1;
s2 = Style1;
enums可以幫你在assignment operation時做型別檢查,避免你在寫程式時指定錯誤的type到enums裡,但是enums也不是所有的型別檢查都會做,考慮以下的清況:
Style s1 = Style1;
// pass and the complier will not say any errors
if (s1 == Area1)
{
// ...
}
為什麼會這樣呢,我想是C++因為沒有Implement operator==(Enum s1, Enum s2)的關係,且Enum可以implicit轉型為int,因此實際上呼叫的是operator==(int s1, int s2)的運算,這樣的結果會造成在enums的equal operation時缺少type-safe,而我認為type-safe對一個常常要mantain多個程式的programmer來說是非常重要的(其實即使只寫一個簡單的程式,我還是希望complier會幫我做type-safe XD),我之前就是碰到類似的問題,我拿別的enums來和我正在使用的enums來比較,並且complier也過了,因此我認為我的程式碼沒有問題了,如果有問題的話我的complier"應該"會告訴我才對,很不辛的,這個問題造成我的程式在客戶端才被發現錯誤(黑箱測試時並沒有測出這個bug orz),而且是在release數個月之後才由user發現的,這所花的成本我想遠比改寫程式為type-safe還花得高,因此後來我也慎重的告誡我們公司的程式設計師,這個type-safe的重要性。
那要怎麼解決這個問題呢,網路上有人寫了一個enums template class來包裝enums,他提供operator==(Enum s1, Enum s2)的運算,並且增加多個enums的bitwise運算(這個下一篇文章再提好了),強化我們的complier的錯誤檢查能力,並提升type-safe。
我使用的是這一個bitwise_enum class
google code的網址是:http://code.google.com/p/bitwise-enum/
目前的版本是1.2版 (http://bitwise-enum.googlecode.com/files/bitwise_enum-1.2.tgz)
#include "bitwise_enums.hpp"
// pass
bitwise_enumss1 = Style1;
// pass
s1 = Style2;
// pass
if (s1 == Style2)
{
// ...
}
// error, your complier will say it can't convert enums 'Area' to 'Style' for equal operation
if (s1 == Area1)
{
// ...
}
Notes:
1.
如果你打算使用bitwise_enums取代現有的寫法的話,因為bitwise_enum用了一些隱喻轉換的constrctor以及non-member operation function,可能會造成你現有的程式碼錯誤,如果要避開這個問題的話,可以將bitwise_enums用namespace包起來。
namesapce utils
{
#include "bitwise_enums.hpp"
}
utils::bitwise_enums1 = Style1;
2. 如果你不擔心enums的type-safe問題的話,那你也就不用這麼麻煩了。 :)
References:
1. bitwise_enums
2. bitwise_enums ComplierErrors
沒有留言:
張貼留言