2 분 소요

모던 C++

개요

열거형은 정수형 상수 집합의 별칭을 정의합니다.

항목 내용
열거형 정의 enum Week {Sunday, Monday};
개체 정의 Week obj = Sunday;
용량 모든 열거자 값을 나타낼 수 있는 정수 형식의 크기.(보통 4byte)

다음과 같이 사용할 수 있습니다.(절대 define쓰지 마세요!!! 매크로 상수 참고)

1
2
3
4
5
enum Week {
    Sunday, Monday, Tuesday, Wednesday, 
    Thursday, Friday, Saturday
};
Week week = Sunday;

다만 상기와 같이 사용하면, 이름의 범위가 충돌되기 쉽기 때문에 클래스(혹은 네임스페이스) 내에 정의하여 이름 범위 충돌을 최소화 하는 것이 좋습니다.(enum Week {eSunday, eMonday...}와 같이 열거형 전용으로 접두어를 쓰는 방법도 있습니다만, 헝가리안 표기같아서 권장하지는 않습니다.)

1
2
3
4
5
6
7
8
9
10
11
class Week {
public:
    // 클래스내에 정의. 사용시 클래스명을 기재해야 함
    enum Val {
        Sunday, Monday, Tuesday, Wednesday, 
        Thursday, Friday, Saturday
    };
};

Week::Val val = Week::Sunday; // 범위 확인 연산자와 클래스명 사용
EXPECT_TRUE(val == Week::Sunday);

(C++11~) 범위 있는 열거형이 추가되어 이름 충돌 회피가 쉬워졌고, 암시적 형변환을 차단하며, 전방 선언도 지원합니다. 클래스 내에 열거형을 정의하지 마시고 범위 있는 열거형을 사용하세요.
(C++20~) using enum이 추가되어 범위 있는 열거형의 이름 없이 열거자를 유효 범위내에서 사용할 수 있습니다.

열거형 값지정

열거형의 각 항목은 이전 항목 + 1 의 값입니다. 디폴트는 0부터 시작하며, 임의 정수값을 지정할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Week {
public:
    enum Val {
        Sunday, // 기본적으로 0부터 시작하여 1씩 증가
        Monday, 
        Tuesday,
        Wednesday = 10, // 값 지정한 이후로 1씩 증가
        Thursday, 
        Friday, 
        Saturday
    };
};

EXPECT_TRUE(
    Week::Sunday == 0 && 
    Week::Monday == 1 && 
    Week::Tuesday == 2 &&
    Week::Wednesday == 10 && // 값 지정한 이후로 1씩 증가
    Week::Thursday == 11 &&
    Week::Friday == 12 && 
    Week::Saturday == 13
);

열거형의 크기

열거형은 모든 열거자 값을 나타낼 수 있는 정수 형식의 크기로 설정됩니다. 따라서 다음 예는 char, short, int 크기중 하나가 될 수 있습니다.

1
2
3
enum MyEnum {a, b, c};

EXPECT_TRUE(sizeof(MyEnum) == sizeof(char) || sizeof(MyEnum) == sizeof(short) || sizeof(MyEnum) == sizeof(int));

따라서, 열거자가 추가되다 보면 어느 순간 sizeof()가 달라질 수 있습니다. 그래서, 파일 저장시에 열거형의 크기만큼 오프셋을 이동하는 코드를이 있으면 호환성이 깨질 수도 있죠. 그래서 크기가 중요한 열거형은 열거자중 더미(Dummy)를 만들어 충분히 큰값을 지정하여 사용합니다.

1
enum MyEnum {a, b, c, MyEnumMax = 0XFFFFFFFF};

(C++11~) 열거형의 기반 타입을 지정할 수 있습니다.

열거형 상수 형변환

열거형

  1. int로 형변환 되고,
  2. intstatic_cast열거형으로 형변환 됩니다만,

타입에 기반한 코딩 계약 을 위반하기 때문에 형변환 하는건 좋지 않습니다.

1
2
3
4
5
6
7
Week::Val val1 = Week::Saturday; // (△) 비권장. 형변환 하지 마세요.
int val2 = Week::Saturday; // (△) 비권장. 열거형 상수는 int 형변환 가능합니다만, 하지 마세요.
EXPECT_TRUE(val1 ==  Week::Saturday);
EXPECT_TRUE(val2 == 13);

val1 = static_cast<Week::Val>(val2 - 1); // (△) 비권장. int는 static_cast로 열거형으로 형변환 가능합니다만, 하지 마세요.
EXPECT_TRUE(val1 ==  Week::Friday);

(C++11~) 범위 있는 열거형이 추가되어 이름 충돌 회피가 쉬워졌고, 암시적 형변환을 차단하며, 전방 선언도 지원합니다.

댓글남기기