系列: C++
cpp
260 行
· 更新於 2026-04-03
enums.cpp
C++/Part2_物件導向/Ch07_結構體與列舉/enums.cpp
// ============================================================
// Ch07 — 列舉(enum / enum class)完整範例
// 編譯:g++ -std=c++17 -Wall -o enums enums.cpp
// ============================================================
#include <iostream>
#include <string>
// ============================================================
// 1. 傳統列舉(Unscoped Enum)
// ============================================================
// 傳統 enum — 值會洩漏到外圍作用域
enum Color {
Red = 0,
Green = 1,
Blue = 2,
};
std::string colorToString(Color c) {
switch (c) {
case Red: return "紅色";
case Green: return "綠色";
case Blue: return "藍色";
}
return "未知";
}
// ============================================================
// 2. 限域列舉(enum class)— 推薦寫法
// ============================================================
// 方向列舉 — 使用 enum class 避免名稱汙染
enum class Direction {
North,
South,
East,
West,
};
std::string directionToString(Direction d) {
switch (d) {
case Direction::North: return "北";
case Direction::South: return "南";
case Direction::East: return "東";
case Direction::West: return "西";
}
return "未知";
}
// ============================================================
// 3. 指定底層型別
// ============================================================
// 星期 — 指定底層型別為 unsigned char(節省空間)
enum class Weekday : unsigned char {
Monday = 1,
Tuesday = 2,
Wednesday = 3,
Thursday = 4,
Friday = 5,
Saturday = 6,
Sunday = 7,
};
std::string weekdayToString(Weekday w) {
switch (w) {
case Weekday::Monday: return "星期一";
case Weekday::Tuesday: return "星期二";
case Weekday::Wednesday: return "星期三";
case Weekday::Thursday: return "星期四";
case Weekday::Friday: return "星期五";
case Weekday::Saturday: return "星期六";
case Weekday::Sunday: return "星期日";
}
return "未知";
}
bool isWeekend(Weekday w) {
return w == Weekday::Saturday || w == Weekday::Sunday;
}
// ============================================================
// 4. 季節列舉 — 搭配函式使用
// ============================================================
enum class Season {
Spring,
Summer,
Autumn,
Winter,
};
struct SeasonInfo {
std::string name;
std::string description;
int avgTempC; // 平均氣溫(攝氏)
};
SeasonInfo getSeasonInfo(Season s) {
switch (s) {
case Season::Spring:
return {"春天", "萬物復甦,百花盛開", 22};
case Season::Summer:
return {"夏天", "陽光普照,適合戶外活動", 32};
case Season::Autumn:
return {"秋天", "秋高氣爽,楓葉轉紅", 20};
case Season::Winter:
return {"冬天", "寒風刺骨,適合圍爐取暖", 10};
}
return {"未知", "", 0};
}
// ============================================================
// 5. HTTP 狀態碼 — enum class 搭配自訂數值
// ============================================================
enum class HttpStatus : int {
OK = 200,
Created = 201,
BadRequest = 400,
Unauthorized = 401,
Forbidden = 403,
NotFound = 404,
ServerError = 500,
};
std::string httpStatusToString(HttpStatus status) {
switch (status) {
case HttpStatus::OK: return "200 OK";
case HttpStatus::Created: return "201 Created";
case HttpStatus::BadRequest: return "400 Bad Request";
case HttpStatus::Unauthorized: return "401 Unauthorized";
case HttpStatus::Forbidden: return "403 Forbidden";
case HttpStatus::NotFound: return "404 Not Found";
case HttpStatus::ServerError: return "500 Internal Server Error";
}
return "Unknown Status";
}
bool isSuccess(HttpStatus status) {
int code = static_cast<int>(status);
return code >= 200 && code < 300;
}
// ============================================================
// main
// ============================================================
int main() {
std::cout << "========================================" << std::endl;
std::cout << " Ch07 列舉(enum / enum class)完整範例" << std::endl;
std::cout << "========================================\n" << std::endl;
// ------ 1. 傳統列舉 ------
std::cout << "【1】傳統列舉(Unscoped Enum)\n" << std::endl;
Color c = Green;
std::cout << " 顏色: " << colorToString(c) << std::endl;
// 傳統 enum 可以隱式轉為 int
int colorValue = c;
std::cout << " Green 的整數值: " << colorValue << std::endl;
// 也可以直接拿來比較整數(這是傳統 enum 的缺點)
if (c == 1) {
std::cout << " ⚠ 傳統 enum 可以與 int 直接比較(不安全)" << std::endl;
}
std::cout << std::endl;
// ------ 2. 限域列舉 ------
std::cout << "【2】限域列舉(enum class)— Direction\n" << std::endl;
Direction dir = Direction::East;
std::cout << " 方向: " << directionToString(dir) << std::endl;
// enum class 不能隱式轉為 int
// int dirValue = dir; // 編譯錯誤!
int dirValue = static_cast<int>(dir);
std::cout << " East 的整數值(顯式轉換): " << dirValue << std::endl;
// 遍歷所有方向
std::cout << " 所有方向:";
for (int i = 0; i <= 3; ++i) {
Direction d = static_cast<Direction>(i);
std::cout << directionToString(d);
if (i < 3) std::cout << "、";
}
std::cout << "\n" << std::endl;
// ------ 3. 指定底層型別 — Weekday ------
std::cout << "【3】指定底層型別 — Weekday\n" << std::endl;
std::cout << " Weekday 佔用空間: " << sizeof(Weekday) << " bytes" << std::endl;
std::cout << " (unsigned char = 1 byte)\n" << std::endl;
Weekday days[] = {
Weekday::Monday, Weekday::Tuesday, Weekday::Wednesday,
Weekday::Thursday, Weekday::Friday, Weekday::Saturday,
Weekday::Sunday,
};
for (auto day : days) {
std::cout << " " << weekdayToString(day)
<< "(值=" << static_cast<int>(day) << ")"
<< (isWeekend(day) ? " ← 週末!" : "")
<< std::endl;
}
std::cout << std::endl;
// ------ 4. 季節列舉搭配結構體 ------
std::cout << "【4】Season 列舉搭配結構體回傳值\n" << std::endl;
Season seasons[] = {Season::Spring, Season::Summer,
Season::Autumn, Season::Winter};
for (auto s : seasons) {
SeasonInfo info = getSeasonInfo(s);
std::cout << " " << info.name << ":"
<< info.description
<< "(平均 " << info.avgTempC << "°C)" << std::endl;
}
std::cout << std::endl;
// ------ 5. HTTP 狀態碼 ------
std::cout << "【5】HttpStatus — enum class 搭配自訂數值\n" << std::endl;
HttpStatus codes[] = {
HttpStatus::OK, HttpStatus::Created,
HttpStatus::NotFound, HttpStatus::ServerError,
};
for (auto code : codes) {
std::cout << " " << httpStatusToString(code)
<< " → " << (isSuccess(code) ? "成功" : "失敗")
<< std::endl;
}
std::cout << std::endl;
// ------ 6. enum class 的型別安全性示範 ------
std::cout << "【6】型別安全性比較\n" << std::endl;
std::cout << " 傳統 enum:" << std::endl;
std::cout << " Color c = Red; // 不需前綴" << std::endl;
std::cout << " int v = c; // 隱式轉換 ✓" << std::endl;
std::cout << " if (c == 0) ... // 與 int 比較 ✓(危險)" << std::endl;
std::cout << "\n enum class:" << std::endl;
std::cout << " Direction d = Direction::East; // 需要前綴" << std::endl;
std::cout << " int v = static_cast<int>(d); // 需顯式轉換" << std::endl;
std::cout << " if (d == Direction::East) ... // 只能同型別比較(安全)" << std::endl;
std::cout << "\n 結論:優先使用 enum class,除非需要與 C 程式碼相容。" << std::endl;
std::cout << "\n========================================" << std::endl;
std::cout << " 範例結束" << std::endl;
std::cout << "========================================" << std::endl;
return 0;
}
相關文章
C++
c
更新於 2026-07-21
deviceAlpha.h
deviceAlpha.h — c source code from the C++ learning materials (C++/Mavis_Homework/FinalProject/deviceAlpha.h).
閱讀文章 →
C++
c
更新於 2026-07-21
finalproject.c
finalproject.c — c source code from the C++ learning materials (C++/Mavis_Homework/FinalProject/finalproject.c).
閱讀文章 →
C++
cpp
更新於 2026-07-21
finalproject.cpp
finalproject.cpp — cpp source code from the C++ learning materials (C++/Mavis_Homework/FinalProject/finalproject.cpp).
閱讀文章 →
C++
c
更新於 2026-07-21
deviceAlpha.h
deviceAlpha.h — c source code from the C++ learning materials (C++/Mavis_Homework/Lab8/deviceAlpha.h).
閱讀文章 →
C++
c
更新於 2026-07-21
lab8.c
lab8.c — c source code from the C++ learning materials (C++/Mavis_Homework/Lab8/lab8.c).
閱讀文章 →
C++
cpp
更新於 2026-07-21
lab8.cpp
lab8.cpp — cpp source code from the C++ learning materials (C++/Mavis_Homework/Lab8/lab8.cpp).
閱讀文章 →