[C++] enum, enum class의 개념 및 사용

유지연·2023년 6월 15일
1

C++

목록 보기
3/7

👋 C++에서 유용하게 쓰이는 enum과 enum class 에 대해 알아보자!


✏️ enum ?

✔️ enum의 정의

C++에는 다양한 자료형이 정의되어 있지만, 필요에 따라 새로운 자료형을 만들어 사용해야 하는 경우가 있다. 이를 사용자 정의 자료형이라고 하는데 enum 열거형은 이 중 가장 간단한 형태의 자료형이다.

"enumerate"라는 영단어의 뜻인 "열거하다"라는 것에서 유추해볼 수 있듯 enum은 여러 값들을 열거하고 이들을 정수형 상수로 매핑하여 사용할 수 있다. 컴파일러는 열거형 멤버들을 정수형 상수로 인식하여 enum 형식의 변수를 인덱싱에 사용하거나, 산술 및 관계형 연산자의 피연산자로 사용할 수 있게 된다.

enum dataStructure 
{
	STACK, QUEUE, HEAP, BINARY_TREE, GRAPH
};

✔️ enum의 사용

위의 예시에서 dataStructure라는 새로운 자료형을 선언하고 STACK, QUEUE, HEAP, BINARY_TREE, GRAPH 라는 데이터를 사용하였다. 따로 초기화된 값이 없다면 제일 앞의 데이터부터 순서대로 0, 1, 2 ... 처럼 0부터 1씩 증가하는 정수값에 대응하게 된다.

enum dataStructure 
{
	STACK, //0에 대응
    QUEUE, //1에 대응
    HEAP, //2에 대응
    BINARY_TREE, //3에 대응
    GRAPH //4에 대응
};

만약 특정한 정수값을 사용하고 싶다면, enum 안에서 원하는 값으로 초기화 시켜주면 된다. 초기화 시키지 않은 데이터들은 이전 데이터의 대응값 + 1 의 값을 가진다.

enum dataStructure 
{
	STACK = 5, //5에 대응
    QUEUE, //6에 대응
    HEAP, //7에 대응
    BINARY_TREE = 10, //10에 대응
    GRAPH = 20 //20에 대응
};

단, 대응하는 정수가 같도록 초기화 시키면 오류가 발생하므로 주의해야한다.

typedef를 사용하여 enum형 변수 선언 시 enum을 생략시킬 수 있다.

typedef enum 
{
	STACK, QUEUE, HEAP, BINARY_TREE, GRAPH
}dataStructre;

int main ( ) {
	dataStructure ds1; //ok
}

✔️ enum의 특징

  • enum 타입의 변수로 바로 입력을 받을 수 없다.
    연산자 오버로딩이 되어있지 않기 때문
enum dataStructure ds1;
cin >> ds1; //ERROR!!
  • enum 타입은 컴파일 시점에 정수형 상수로 변환되어 int와 비교했을 때 성능 저하가 없다.
  • enum 타입에는 enum 값 이외의 다른 값을 대입할 수 없다.
  • 관련값들을 하나로 묶어 사용하면서 가독성 및 소스코드의 이해도를 높일 수 있다.
  • 다른 enum 영역이더라도 변수명이 같으면 안된다.
    → 이 문제를 해결하기 위해 C++11에 등장한 것이 enum class
enum johnFamily
{
	JOHN, MARK, SALLY, KIM
};

enum tomFamily 
{
	TOM, KIM, BRWON, JENNY  //johnFamily enum에 이미 KIM 이라는 이름의 변수가 존재함
};

✏️ enum class?

✔️ enum class의 등장

앞에서 잠깐 언급했듯, 기존의 enum에서는 enum 영역이 다르더라도 같은 이름의 변수가 있으면 컴파일러가 해당 변수가 어떤 enum에 속하는 데이터인지 알 수 없다는 문제점이 있었다.

int main ( ) {
	int class_number = KIM //Error!
    return 0;
}

이를 방지하기 위해 별도로 각 enum에 namespace를 만들어서 사용하거나, 변수명을 수정하는 등 번거로운 과정이 필요했다. 이러한 enum의 단점을 보완하기 위해 C++11에서 enum class라는 개념이 등장하였다.

✔️ enum class의 사용

기존의 enum 선언 문법에서 enum 옆에 class만 붙여주면 간단히 enum class를 사용할 수 있다.
또한 해당 데이터 호출 시 열거형 이름::열거자 형태로 사용하면 된다.

enum class johnFamily
{
	JOHN, MARK, SALLY, KIM
};

enum class tomFamily 
{
	TOM, KIM, JENNY, BROWN
};

int main ( ) {
	int num = static_cast<int> (tomFamily::KIM);
    cout << "Kim of Tom's Family: " << num << "|n";
    return 0;
}

✔️ enum class의 특징

  • 기존의 enum과 달리 암시적 형변환이 이루어지지 않는다.
enum week 
{
	SUN, MON, TUE, WED, THU, FRI, SAT
};

int main ( ) {
	if (MON == 1) cout << "Monday is 1. \n";
    //암시적으로 week 타입의 변수 MON이 정수 1로 변환되기 때문에 int형 변수와 비교연산 가능
    else cout << "Monday is not 1. \n";
}

위의 코드처럼 enum을 사용하는 경우는 따로 형변환을 해주지 않아도 암시적으로 정수형 상수로 변환되어 사용이 가능하였다. 하지만 enum class에서는 cast 연산자를 통해 명시적으로 형변환을 해주어야 한다.

enum class week
{
	SUN, MON, TUE, WED, THU, FRI, SAT
};

int main ( ) {
	if (static_cast<int>(MON) == 1) cout << "Monday is 1. \n";
    //cast 연산자를 통해 week형을 int로 명시적 형변환
    else cout << "Monday is not 1. \n";
}
  • 동일한 변수명에 대한 충돌을 효과적으로 방지할 수 있다.


자구알 공부하다가 예제 코드에 enum class가 나왔는데 잘 모르는 개념이라 공부하고 넘어가는게 좋을 것 같아서 정리해보았따. 사실 C++도 아직 모르는 문법이나 개념들이 너무 많아서 예제 코드 볼 떄마다 새롭게 공부해야하는 친구들이 생긴다. 그래서 자구알만 해도 오래걸리는데 더 더 시간이 오래걸리는 😵

그래도 뭔가 하나 하나 공부할 때마다 내가 쓸 수 있는 방법들이 차곡차곡 쌓이는 것 같아서 뿌듯하다!!

[내용 참고] https://blockdmask.tistory.com/405
https://learn.microsoft.com/ko-kr/cpp/cpp/enumerations-cpp?view=msvc-170

profile
Keep At It

0개의 댓글