[C++] enum

꿈별·2023년 7월 23일
0

C++

목록 보기
24/27

✔enum

열거형이라고 부름

  • 타입 이름 나열하면, 컴파일러는 0부터 연속된 숫자로 받아들임
// 열거형
enum MY_TYPE
{
	TYPE_1, // 0
	TYPE_2, // 1
	TYPE_3, // 2
};
  • a == 2
int a = TYPE_3;
  • 숫자를 직접 지정하는 것도 가능하다.
    숫자를 지정한 다음부터는 지정했던 수에서 연속된 숫자로 나열된다(?)
TYPE_5 = 100;
TYPE_6,	 101;
  • ❗ enum은 다른 enum의 이름과 겹칠 수도 있다.
enum MY_TYPE
{
	TYPE_1, // 0
	TYPE_2, // 1
	TYPE_3, // 2
};

enum OTHER_TYPE
{
	TYPE_1,
};

-> 이러면 다른 클래스에서 TYPE_1을 호출할 때,
MY_TYPE의 것인지 OTHER_TYPE의 것인지 구분할 수 없어 모호해진다.
(재정의 오류)

  • 💡enum 클래스
    enum 클래스를 쓰면 반드시 몸체까지 같이 정의해서 호출해야 한다.
    그리고 타입이름(MY_TYPE)을 자료형으로 보기 때문에, 만약 정수로 바꾸고 싶다면
    명시적으로 캐스팅을 해줘야 한다.
int a = (int)MY_TYPE::TYPE_1;
  • 최신 VS 컴파일러는 그냥 enum을 쓰면 경고하기도 함

✔define

전처리기로 정의해두는 동작이 enum이랑 비슷해 보인다

#define CLASS_1 0
#define CLASS_2 1
#define CLASS_3 2
  • enum vs #define 차이점?
    전처리기는 컴파일 이전에 실행된다.
    따라서 #define의 경우, 코드에 작성된 상수명을 상수에 초기화한 값으로
    단순히 치환하게 된다.
    문제가 생겨도 상수 값만 남아있어서, 그게 어떤 의미인지 사용자가 직접 찾아봐야 한다

  • enum은 enum의 이름 정보 자체가 심볼테이블에 남음(??)
    따라서 디버깅할 때, 단순히 치환되는 게 아니라, 특정 타입(MY_TYPE)의, TYPE_1 의 값을 썼다고 생각하게 됨
    이 과정이 시각적으로 남아있기 때문에 컴파일러가 인식할 수 잇음


활용하기

enum을 활용해서, 이전에 BST를 구현할 때 만든 insert 함수의 대칭적인 코드들을
개선해 보자

  • 같은 자료형이 나열된 것이므로 배열로 묶을 수 있다.
enum class NODE_TYPE
{
	PARENT, // 0
	LCHILD, // 1
	RCHILD, // 2
	END,	// 3
};
template <typename T1, typename T2>
struct tBSTNode
{
	tPair<T1,T2>	pair;
	tBSTNode*		arrNode[(int)NODE_TYPE::END];

-> tBSTNode 타입 포인터 3개로 묶는다.
이 때 enum의 END가 3이므로 END로 명시한다..
`

  • 생성자 만들기
    insert()에서 노드 포인터 객체 생성할 때, 인자로 어차피 pair 빼면 어디에 넣을 지 정한 게 아니라서 다 널포인터임.
    pair만 받아오는 생성자는 굳이 만들필요 X

  • 내가 갈 방향을 enum의 타입으로 지정해 보기.

    • 처음엔 일단 END로 초기화해 두고,
    • 새 노드의 방향에 따라 열거형 변수를 RCHILD, LCHILD로 초기화해 준다.
    • 중복키를 허용하지 않으므로, 두 노드의 값이 같을 때는 함수 종료함.
  • node_type에 삽입할 방향을 이미 담고 있기 때문에 대칭되던 코드를 간결하게 줄일 수 있다.

// 수정 후
while(true)
{
	if (pNode->pair.first < pNewNode->pair.first)
		node_type = NODE_TYPE::RCHILD;
	else if (pNode->pair.first > pNewNode->pair.first)
		node_type = NODE_TYPE::LCHILD;
	else
		return false;

		if (nullptr == pNode->arrNode[(int)node_type])
		{
			pNode->arrNode[(int)node_type] = pNewNode;
			pNewNode->arrNode[(int)NODE_TYPE::PARENT] = pNode;
			break;
		}
		else
		{
			pNode = pNode->arrNode[(int)node_type];
		}
}

💡 이렇게 코드를 간결하게 적을 수 있었던 가장 큰 이유는
노드 포인터를 배열로 만들어서 인덱스로 지칭할 수 있게 되었기 때문임.

(참고
열거형의 변수는 해당 형식으로 정의된 열거형 집합의 값 중 하나를 저장한다.)



[참고]
https://youtu.be/mWk4-YyeZfA
https://learn.microsoft.com/ko-kr/cpp/c-language/c-enumeration-declarations?view=msvc-170

0개의 댓글