Enumeration
enum คือ Type ที่เก็บค่าตัวเลข integer ที่ผู้ใช้กำหนดโดยสามารถตั้งชื่อ (named) ให้กับค่านั้นๆ ได้ เรียกว่า enumerators เช่น enum class Color {red, green, blue}; เป็นการกำหนด enumeration ชื่อ Color โดยมี enumerators ชื่อ red, green, blue เป็นต้น
Enum class
enum class Traffic_light{red,yellow,green};
void SelectLight(Traffic_light x)
{
switch (x)
{
case Traffic_light::red:
cout <<"("
<< static_cast(Traffic_light::red)
<< "):Stop!!!" << "\n";
break;
case Traffic_light::yellow:
cout << "("
<< static_cast(Traffic_light::yellow)
<< "):Slow down..." << "\n";
break;
case Traffic_light::green:
cout << "("
<< static_cast(Traffic_light::green)
<< "):Go Go" << "\n";
break;
default:
break;
}
}
int main()
{
Traffic_light light;
light = Traffic_light::red;
SelectLight(light);
}
//แสดงผล
(0):Stop!!!
enumerators โดยปกติแล้วถ้าไม่กำหนดค่าให้ by default จะเริ่มต้นจาก 0 และเพิ่มขึ้นทีละ 1 ไปเรื่อยๆ ตามจำนวน enumerator เนื่องจาก enum เป็นการเก็บค่าตัวเลขดังนั้นขนาดของ enum จึงมีขนาดเท่ากับ integer หรือ sizeof(int) นั่นเอง แต่หากต้องการลดขนาดของหน่วยความจำที่ไม่จำเป็นเพราะ enumerators มีไม่เยอะ เราสามารถกำหนดเป็น char แทนได้ดังนี้
- enum class Traffic_light : int {red,yellow,green} //โดยปกติจะเป็น integer เพราะฉะนั้นขนาดจะเท่ากับ sizeof(int) คือ 4 byte (ขึ้นอยู่กับ compiler)
- enum class Traffic_light : char {red,yellow,green} //เปลี่ยนเป็น char ขนาดจะเท่ากับ sizeof(char) คือ 1 byte เท่านั้น
เราสามารถกำหนดค่าให้กับ enumerator ได้เช่น
enum class Printer_Flag
{
none = 0,
acknowledge = 1,
paper_empty = 2,
busy = 4,
out_of_black = 8,
out_of_color= 16
};
enum สามารถดำเนินการ bitwise โดยการกำหนดให้สามารถใช้ operator | และ & ได้ดังนี้
//define bitwise operator for | and &
constexpr Printer_Flag operator|(Printer_Flag a, Printer_Flag b)
{
return static_cast(static_cast(a) | static_cast(b));
}
constexpr Printer_Flag operator&(Printer_Flag a, Printer_Flag b)
{
return static_cast(static_cast(a) & static_cast(b));
}
//try to print by checking flag before print
void Try_to_Print(Printer_Flag p)
{
if ((p&Printer_Flag::acknowledge) != Printer_Flag::none)
{
// do something ....
}
else if ((p & Printer_Flag::busy) != Printer_Flag::none)
{
// do something ....
}
else if ((p & (Printer_Flag::out_of_black|Printer_Flag::out_of_color)) != Printer_Flag::none)
{
// do something ....
}
}
Plain enum
การเขียน enum แบบไม่มี class สามารถทำได้แต่จะต้องระวังการใช้ให้ดีเพราะบางกรณีจะไม่ error เช่น
enum Traffic_light{red,yellow,green};
enum Warning { green,yellow,orange,red};
void f(Traffic_light x)
{
if (x == red) //จาก enum ไหนกันแน่ต้องตรวจสอบให้ดี
{
//do something...
}
else if (x == Warning::red) //ได้เฉยไม่ error ด้วย
{
//do something...
}
}
int main()
{
int a1 = green; //ไม่ error แต่ไม่รู้ว่า green ไหน
int a2 = Warning::green; //OK แบบนี้ไม่มีปัญหา
}
การใช้ enum แบบนี้อาจมีปัญหาทำให้สับสนได้
