C++에는 많은 자료형이 내장되어 있다. 하지만 이 자료형들이 원하는 걸 표현하기에 항상 충분하지는 않다. 그래서 C++은 프로그래머들이 자신만의 자료형을 만들 수 있게 해 주는 기능을 포함하고 있다.
이러한 자료형을 사용자 정의 자료형이라고 한다.아마도 가장 간단한 사용자 정의 자료형은 열거된 유형일 것이다.
열거된 유형(열거형이라고도 함)은 가능한 모든 값이 기호 상수(열거형)로 정의되는 자료형이다. 열거형은 enum 키워드를 통해 정의된다.
출처: https://boycoding.tistory.com/179 [소년코딩:티스토리]
//열거형 예시
enum dataStructure
{
STACK = 5, //5에 대응
QUEUE, //6에 대응
HEAP, //7에 대응
BINARY_TREE = 10, //10에 대응
GRAPH = 20 //20에 대응
};
enum 타입에는 enum 값 이외의 다른 값을 대입할 수 없다. 이유는?
연산자 오버로딩이 되어있지 않기 때문에 오류가 발생한다.
열거형을 잘 사용한다면 가독성을 손쉽게 높일 수 있는데 무분별하게 사용하면 중복 문제가 발생한다.
Enum 예제 코드 출처
enum johnFamily
{
JOHN, MARK, SALLY, KIM
};
enum tomFamily
{
TOM, KIM, BRWON, JENNY //johnFamily enum에 이미 KIM 이라는 이름의 변수가 존재함
};
서로 다른 이름의 열거형에 들어가있더라도 같은 이름을 사용하면 재정의 문제가 발생한다. 그렇기에 John_KIM, Tom_KIM과 같은 방식으로 다르게 설정해 문제를 예방하기도 하지만 Enum Class를 이용해 문제를 해결하는 방식이 있다.
Enum Class는 Enum에서 발생하는 재정의 문제를 해결 할 수 있다.
기존의 enum은 열거형 값들이 전역 네임스페이스에 놓인다. 따라서 다른 열거형과 값이 충돌할 수 있다. 하지만 Enum class는 열거형 값들이 열거형의 네임스페이스 안에 포함되기 때문에 이름 충돌이 발생하지 않는다.
#include <iostream>
enum class johnFamily
{
JOHN, MARK, SALLY, KIM
};
enum class tomFamily
{
TOM, KIM, BROWN, JENNY
};
int main() {
johnFamily john = johnFamily::JOHN;
tomFamily tom = tomFamily::KIM; // 이름 충돌이 발생하지 않음
// std::cout << john << std::endl; // 오류: 직접 출력할 수 없음
// std::cout << tom << std::endl; // 오류: 직접 출력할 수 없음
std::cout << static_cast<int>(john) << std::endl; // 0
std::cout << static_cast<int>(tom) << std::endl; // 1
return 0;
}
Enum Class를 사용하면 충돌 문제를 효과적으로 해결 할 수 있지만 형변환을 해야하는 귀찮음이 존재한다.
static_cast<int>(변수명)
그렇기에 일반 열거형을 사용하되 이름을 구분해 충돌문제를 방지하던지 혹은 static_cast()를 사용하던가 지시자(Define)을 이용해 손쉽게 사용 할 수 있게 바꾸는 것 중 선택해야 한다.
#include <iostream>
//지시자 사용
#define ENUM_TO_INT(value) static_cast<int>(value)
enum class johnFamily {
JOHN, MARK, SALLY, KIM
};
int main() {
johnFamily john = johnFamily::JOHN;
std::cout << ENUM_TO_INT(john) << std::endl;
return 0;
}