Menu
Coddy logo textTech

Enum 클래스와 강력한 타이핑

Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 104개 중 80번째.

C++11에서는 기존 C 스타일 열거형의 한계를 해결하기 위해 enum classes(범위 지정 열거형이라고도 함)를 도입했습니다. 이는 더 강력한 형식 안전성을 제공하고 열거형 값의 우발적인 오용을 방지합니다.

기존 enum에는 문제가 있습니다. 해당 값이 주변 범위로 누출되고 암묵적으로 정수로 변환되어 미묘한 버그가 발생합니다:

// 전통적인 enum - 문제가 있음
enum Color { Red, Green, Blue };
enum TrafficLight { Red, Yellow, Green };  // 오류! Red와 Green이 이미 정의됨

int x = Red;  // 암시적으로 int로 변환됨 (0)
if (Red == 0) { }  // 컴파일됨 - enum을 int와 비교

열거형 클래스는 값을 스코프로 제한하고 암시적 변환을 방지하여 이러한 문제를 해결합니다:

enum class Color { Red, Green, Blue };
enum class TrafficLight { Red, Yellow, Green };  // OK - 충돌 없음

Color c = Color::Red;      // 스코프 연산자를 사용해야 함
// int x = c;              // Error! 암시적 변환 없음
int x = static_cast<int>(c);  // 명시적 변환이 필요함

// if (c == 0) { }         // Error! int와 비교할 수 없음
if (c == Color::Red) { }   // OK - 같은 타입 비교

메모리 제어를 위해 기반 타입을 지정할 수도 있습니다:

enum class Status : uint8_t {
    Inactive = 0,
    Active = 1,
    Pending = 2
};

Enum 클래스는 OOP 설계와 잘 통합되어 코드를 더 읽기 쉽게 만들고, 런타임이 아닌 컴파일 타임에 타입 오류를 잡아냅니다.

challenge icon

챌린지

쉬움

서로 다른 우선순위 수준과 작업 상태를 나타내기 위해 enum 클래스를 사용하는 작업 우선순위 시스템을 만들어 보겠습니다. 이를 통해 enum 클래스가 어떻게 타입 안전성을 제공하고 기존 enum에서 발생하는 종류의 bug를 방지하는지 알아볼 수 있습니다.

코드를 세 개의 파일로 구성합니다:

  • TaskTypes.h: 작업 시스템을 위한 enum 클래스를 정의합니다.

    Priority enum 클래스를 만들고 다음 값을 지정합니다: Low, Medium, High, Critical. 기본 타입으로 int를 지정하고, 각각에 1, 2, 3, 4의 값을 할당합니다.

    Status enum 클래스를 만들고 다음 값을 지정합니다: Pending, InProgress, Completed.

    두 개의 헬퍼 함수를 제공합니다:

    • priorityToString(Priority p): 우선순위를 문자열로 반환합니다 ("Low", "Medium", "High", 또는 "Critical")
    • statusToString(Status s): 상태를 문자열로 반환합니다 ("Pending", "InProgress", 또는 "Completed")
  • Task.h: enum 클래스를 사용하는 Task 클래스를 정의합니다.

    Task는 이름(문자열), Priority, Status를 저장해야 합니다. 생성자는 이름과 우선순위를 받아야 하며, 상태의 기본값은 Status::Pending이어야 합니다.

    다음 메서드를 구현합니다:

    • setStatus(Status s): 작업의 상태를 업데이트합니다
    • getPriorityValue(): static_cast를 사용하여 우선순위의 기본 정수 값을 반환합니다
    • display(): 작업을 다음 형식으로 출력합니다: [name] - Priority: [priority] (Value: [value]) - Status: [status]
  • main.cpp: 세 개의 입력을 읽습니다:
    1. 작업 이름(문자열)
    2. 정수로 입력된 우선순위 수준(1=Low, 2=Medium, 3=High, 4=Critical)
    3. 정수로 입력된 상태(0=Pending, 1=InProgress, 2=Completed)

    입력된 이름과 우선순위로 Task를 생성합니다( static_cast를 사용하여 정수를 적절한 Priority enum 값으로 변환합니다). 그런 다음 세 번째 입력을 기준으로 상태를 설정합니다. 마지막으로 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: Pending

enum 클래스가 우선순위 값과 상태 값을 어떻게 완전히 분리하는지 살펴보세요. PriorityStatus와 실수로 비교하거나 서로 대입할 수 없습니다. 정수와 enum 값 사이를 변환할 때 필요한 명시적인 static_cast는 코드의 의도를 분명하게 만들고 미묘한 bug를 방지합니다.

직접 해보기

#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;
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 C++ 컴파일러