Bilindiği gibi C++03’te enum sabitleri (enumerators) enum ismi ile aynı faaliyet alanına sahiptir. Yani C++03’te enum ismini niteliksiz olarak (unqualified) kullanabildiğimiz her yerde enum sabitlerini de kullanabiliriz. Örneğin:
enum Days {
Sunday, Monday, Tuesday, Wednesday,
Thursday, Friday, Saturday
};
void Foo()
{
Days d;
d = Monday; // geçerli
// ...
}
Bu kural bizim aynı faaliyet alanı içerisinde aynı isimli başka bir değişken bildirimi yapmamızı engellemektedir. Örneğin:
enum Days {
Sunday, Monday, Tuesday, Wednesday,
Thursday, Friday, Saturday
};
int Monday; // geçersiz!
enum sabitlerinin faaliyet alanlarının sınırlandırılması için sarma bir sınıftan faydalanılabilir:
struct Week {
enum Days {
Sunday, Monday, Tuesday, Wednesday,
Thursday, Friday, Saturday
};
};
Week::Days day;
day = Week::Monday; // geçerli
Halbuki C# ve Java gibi dillerde enum sabitlerinin faaliyet alanı enum bloğu ile sınırlıdır. Bunları dışarıdan kullanmak için enum ismiyle niteliklendirmek gerekir. Aşağıdaki C# örneğini inceleyiniz:
enum Days
{
Sunday, Monday, Tuesday, Wednesday,
Thursday, Friday, Saturday
}
//...
Days day;
day = Days.Monday;
C++03’te enum türlerinin ilişkin olduğu tamsayı türleri (underlying integer types) derleyici tarafından belirlenir; programcı bunu açıkça belirleyemez. Yine C++03’teki klasik enum türleri doğrudan tamsayı türlerine dönüştürülebilir. Bu dönüştürmenin tür güvenliği bakımından sorunlu bir durum oluşturduğunu söyleyebiliriz. Örneğin:
void Foo(int);
//
Foo(Staurday); // geçerli
Üstelik işlem öncesi otomatik tür dönüştürmesi sırasında enum türleri tamsayı türlerine dönüştürüldüğü için farklı enum türlerinin aritmetik operatörlerle ve karşılaştırma operatörleriyle işleme sokulabilmesi hepten güvensiz bir durum oluşturmaktadır:
enum Days {
Sunday, Monday, Tuesday, Wednesday,
Thursday, Friday, Saturday
};
enum Colors {
Red, Green, Blue
};
//...
Days day = Wednesday;
Colors color = Green;
int result;
result = day + color; // geçerli
if (day > color) { // geçerli
//...
}
C++0x’te enum türlerinin yukarıda sözü edilen olumsuz özellikleri yeni enum türleriyle giderilmeye çalışılmıştır. Yeni enum türleri enum class ya da enum struct anahtar sözcükleriyle bildirilir. Bu iki bildirim arasında bir farklılık yoktur.[1] Örneğin:
enum class Days {
Sunday, Monday, Tuesday, Wednesday,
Thursday, Friday, Saturday
};
enum struct Colors {
Red, Green, Blue
};
Bu yeni enum türlerine ilişkin enum sabitlerinin faaliyet alanı enum bloğu ile sınırlıdır. Blok dışından ancak :: operatörü ile niteliklendirilerek kullanılabilir. Örneğin:
Days day;
day = Monday; // geçersiz!
day = Days::Monday; // geçerli
Bu yeni enum türleri ile tamsayı türleri arasında doğrudan (implicit) dönüştürme yoktur. Örneğin:
Days day = Days::Monay;
int result;
result = day; // geçersiz!
result = (int) day; // geçerli
Yeni enum türleri işlem öncesinde tamsayı türlerine de dönüştürülmezler:
Days day = Days::Wednesday;
Colors color = Colors::Green;
int result;
result = day + color; // geçersiz!
if (day > color) { // geçersiz!
//...
}
if (day) { // geçersiz! bool türüne de doğrudan dönüştürme yok!
//...
}
Yeni enum türlerinin ilişkin olduğu tamsayı türleri : <tür> sentaksıyla belirlenebilmektedir. Örneğin:
enum class Test : long {
AA, BB, CC
};
Yeni enum türlerinde ilişkin olunan tamsayı türü belirtilmezse sanki int belirtilmiş gibi işlem görür. enum sabitlerinin değerleri ilişkin olunan tamsayı türlerinin sınırlarını aşamaz. Örneğin:
enum struct Colors : unsigned char {
Red = 254, Green, Blue // geçersiz! Blue değeri sınırı aşmış
};
C++03’teki enum türleri C++0x’te geçmişe doğru uyumu korumak için aynı biçimde bırakılmıştır. Fakat bu eski enum türleri de istenirse :: operatörü ile nitelikli olarak kullanılabilir. Fakat yine enum sabitlerinin faaliyet alanı aynıdır. Örneğin:
enum Colors {
Red, Green, Blue
};
//...
Colors color1 = Green; // geçerli
Colors color2 = Colors::Green; // geçerli
C++0x’teki bu yeni enum türlerinin hem sentaks hem de semantik bakımdan C#’taki enum türlerine çok benzemektedir...
[1] C++0x standart taslaklarında eski enum türlerine unscoped enumerations, yeni enum türlerine ise scoped enumerations denilmektedir.
Kaynaklar
1. Miller, E., Sutter, H., & Stroustrup B. (2007). Strongly Typed Enums (3 Revisions) - (N2347). http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/adresinden alınmıştır.
2. Working Draft, Standard for Programming Language C++ (N2798=08-0308). (2008). http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/ adresinden alınmıştır.
CSD C ve Sistem Programcıları Derneği