16. enum (열거형)

  1. 정의
  2. 특징



1. 정의

추가로, switch 조건문과 같이 잘 쓰이는 것이 열거형(enum)이다.

열거형은 말 그대로 사용자가 직접 열거하여 정의하는 자료형이다. 열거형으로 선언된 변수는 열거형에 지정된 값만 넣을 수 있으며, 4바이트 정수 타입이다.

열거형에서 선언되는 변수들은 선언 시 정수로 초기화할 수 있으며, 사용자가 지정하여 초기화하지 않을 경우 최초 변수는 0부터, 이후의 변수는 앞 변수 값에 1을 더한 값이 할당된다.


enum 뒤에 class를 붙이지 않고 열거형을 선언할 수 도 있지만, 이 경우 열거형 내부에 선언된 변수의 이름이 중복되면 컴파일 중 재정의 오류가 발생한다.

따라서 열거형을 선언할 때에는 되도록 class 를 붙이는 것을 권장한다.

enum 은 암시적 형변환이 이루어지지만, enum class 의 경우 정수 자료형으로 사용하려면 별도의 명시적 형변환이 필요하다.

enum class State
{
	bleed,	// 0 할당
	iced = 1 << 1,	// 2 할당
	fired = 1 << 2,	// 4 할당
	chaos,		// 5 할당
	stunned,	// 6 할당
};


int main()
{
	State player_state = State::chaos;

	switch (player_state)
	{
	case State::bleed:
		cout << "bleed\n";
		break;
	case State::iced:
		cout << "iced\n";
		break;
	case State::fired:
		cout << "fired\n";
		break;
	case State::chaos:
		cout << "chaos\n";      //chaos 가 출력됨
		break;
	case State::stunned:
		cout << "stunned\n";
		break;
	default:
		break;
	}

	return 0;
}



2. 특징

열거형은 전처리기 #define 과 비슷하게 동작하는 것 처럼 보이지만, 차이점이 있다.

전처리기 #define 은 말그대로 전처리기이기 때문에 컴파일되기 전에 먼저 처리하여 해당 구문에 일치하는 변수들을 미리 치환해 둔다.

그래서 이후 디버깅 중 어떤 변수에 전처리기를 이용한 값을 넣을 경우 치환된 값 자체로 보이게 되어, 프로그램이 의도대로 동작하는지 한눈에 알기 어렵다.


예를 들어, #define BURN 1 으로 전처리기를 이용해 사전에 정의한 값을 int state = BURN 처럼 변수에 값을 넣었다고 하자.

이 경우 디버깅 중에는 state 변수 안에 int 값 1이 들어가있는 것으로 보인다.

다만 열거형을 이용할 경우 state = (int)STATE::ICED 로 값을 대입하면 이후 디버깅 중 STATE::ICED 의 값 0 이 아닌 STATE::ICED 자체를 확인할 수 있다.

이는 디버깅 중 코드의 가시성을 향상시키기에 프로그램이 의도대로 동작하는지 확인하기 쉬워진다.


다만 전처리기 #define 는 열거형이라는 자료형에 한정되지 않기에 훨씬 다양한 사용처에서 쓰인다.


#define BURN 1

enum class STATE {
	ICED
};

int main() {

	int state1 = BURN;	// int 값 1로 저장됨

	STATE state2(STATE::ICED);	// ICED(0) 으로 저장됨. 실제로 ICED는 0이지만 값이 ICED 임을 알 수 있으며, 타입은 STATE이다.

	return 0;
}