Enum 클래스와 강력한 타이핑
Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 104개 중 80번째.
C++11은 기존 C 스타일 열거형의 단점을 해결하기 위해 enum classes(범위가 지정된 열거형이라고도 함)를 도입했습니다. 이들은 더 강력한 타입 안전성을 제공하며 열거형 값의 실수로 인한 오용을 방지합니다.
전통적인 열거형(enum)에는 문제가 있습니다. 열거형의 값들이 주변 스코프로 유출되고 정수로 암시적 변환되어, 미묘한 버그를 유발할 수 있습니다:
// 전통적인 열거형 - 문제 발생 가능
enum Color { Red, Green, Blue };
enum TrafficLight { Red, Yellow, Green }; // 오류! Red와 Green이 이미 정의됨
int x = Red; // int(0)로 암시적 변환됨
if (Red == 0) { } // 컴파일됨 - 열거형과 정수 비교열거형 클래스(Enum classes)는 값의 범위를 제한하고 암시적 변환을 방지하여 이러한 문제를 해결합니다:
enum class Color { Red, Green, Blue };
enum class TrafficLight { Red, Yellow, Green }; // OK - 충돌 없음
Color c = Color::Red; // 범위 지정 연산자를 사용해야 함
// int x = c; // 오류! 암시적 변환 없음
int x = static_cast<int>(c); // 명시적 변환 필요
// if (c == 0) { } // 오류! int와 비교할 수 없음
if (c == Color::Red) { } // OK - 동일한 타입 비교메모리 제어를 위해 기본 타입을 지정할 수도 있습니다:
enum class Status : uint8_t {
Inactive = 0,
Active = 1,
Pending = 2
};Enum 클래스는 OOP 설계와 잘 통합되어, 코드를 더 읽기 쉽게 만들고 런타임이 아닌 컴파일 타임에 타입 오류를 잡아낼 수 있게 해줍니다.
챌린지
쉬움서로 다른 우선순위 레벨과 작업 상태를 나타내기 위해 enum 클래스를 사용하는 작업 우선순위 시스템을 구축해 보겠습니다. 이는 enum 클래스가 어떻게 타입 안전성을 제공하고 기존 enum에서 발생하는 버그를 방지하는지 보여줍니다.
코드는 다음 세 개의 파일로 구성됩니다:
TaskTypes.h: 작업 시스템을 위한 enum 클래스들을 정의합니다.Low,Medium,High,Critical값을 가지는Priorityenum 클래스를 생성하세요. 기본 타입을int로 지정하고, 각각 1, 2, 3, 4의 값을 할당합니다.Pending,InProgress,Completed값을 가지는Statusenum 클래스를 생성하세요.두 개의 헬퍼 함수를 제공하세요:
priorityToString(Priority p)— 우선순위를 문자열("Low", "Medium", "High", 또는 "Critical")로 반환합니다.statusToString(Status s)— 상태를 문자열("Pending", "InProgress", 또는 "Completed")로 반환합니다.
Task.h: 정의한 enum 클래스들을 사용하는Task클래스를 정의합니다.Task는 이름(string),Priority,Status를 저장해야 합니다. 생성자는 이름과 우선순위를 인자로 받으며, 상태는 기본적으로Status::Pending으로 설정되어야 합니다.다음 메서드들을 구현하세요:
setStatus(Status s)— 작업의 상태를 업데이트합니다.getPriorityValue()—static_cast를 사용하여 우선순위의 기본 정수 값을 반환합니다.display()— 작업을[name] - Priority: [priority] (Value: [value]) - Status: [status]형식으로 출력합니다.
main.cpp: 세 개의 입력을 읽습니다:- 작업 이름 (string)
- 정수 형태의 우선순위 레벨 (1=Low, 2=Medium, 3=High, 4=Critical)
- 정수 형태의 상태 (0=Pending, 1=InProgress, 2=Completed)
주어진 이름과 우선순위로
Task를 생성하세요 (static_cast를 사용하여 정수를 적절한Priorityenum 값으로 변환합니다). 그런 다음 세 번째 입력을 기반으로 상태를 설정합니다. 마지막으로display()를 호출하여 작업 세부 정보를 표시합니다.
예를 들어, 입력이 Fix bug, 3, 1인 경우:
Fix bug - Priority: High (Value: 3) - Status: InProgress입력이 Write docs, 1, 2인 경우:
Write docs - Priority: Low (Value: 1) - Status: Completed입력이 Deploy app, 4, 0인 경우:
Deploy app - Priority: Critical (Value: 4) - Status: Pendingenum 클래스가 우선순위와 상태 값을 어떻게 완전히 분리하여 유지하는지 확인해 보세요. Priority와 Status를 실수로 비교하거나 서로 할당할 수 없습니다. 정수와 enum 값 사이의 변환에 필요한 명시적인 static_cast는 코드의 의도를 명확하게 하고 미묘한 버그를 방지합니다.
직접 해보기
#include <iostream>
#include <string>
#include "Task.h"
using namespace std;
int main() {
// 입력 읽기
string taskName;
int priorityInt;
int statusInt;
getline(cin, taskName);
cin >> priorityInt;
cin >> statusInt;
// TODO: 주어진 이름과 우선순위로 Task 생성
// static_cast를 사용하여 priorityInt를 Priority 열거형으로 변환
// TODO: statusInt를 기반으로 작업의 상태 설정
// static_cast를 사용하여 statusInt를 Status 열거형으로 변환
// TODO: display()를 호출하여 작업 세부 정보 표시
return 0;
}이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.