본문 바로가기
C │ C++ │ C#/C++

C++ Chapter 4.6 : 열거형과 열거형 클래스

by Pokaa 2023. 8. 20.
728x90
728x90
SMALL
열거형 enum


열거형이 필요한 이유

  • weapon_id = 1이면 칼, 2이면 방패, 3이면 해머 등등… 이런걸 다 외울 수가 없음
  • 그냥 SWORD 만 쳐도 1에도 대응될 수 있다면 편할 것 같다 !


새롭게 사용자 정의 자료형을 만들어준다!

enum Color
{
    COLOR_BLACK,  // 0에 대응
    COLOR_RED,  // 1에 대응
    COLOR_BLUE,  // 2에 대응
    COLOR_GREEN,  // 3에 대응
};

int main()
{
    Color paint = COLOR_BLACK; // paint 에 내부적으로는 0이 들어가게 됨
    Color house(COLOR_BLUE); // house에 내부적으로는 2가 들어가게 됨
    Color apple(COLOR_RED); // apple에 내부적으로 1이 들어가게 됨 

    std::cout << paint << std::endl; // 정수 0이 나올 것.
}
  • Color 라는 새로운 자료형을 만듬
    ο 이 자료형의 데이터 종류로는 COLOR_BLACK, COLOR_RED, COLOR_BLUE, COLOR_GREEN 가
       있으며
     각각 내부적으로 정수 0, 1, 2, 3으로 작동한다.
    ο paint 를 출력하면 0이 나올 것.


정의 방법

  • 대문자로 키워드들을 적어주면 처음부터 차례로 정수 0, 1, 2, 3 에 대응됨
    ο 값을 지정 안해준다면 이렇게 0부터 시작하여 0,1,2,3 대응되는데
        ■ 값을 직접 지정해주는 것도 가능하다.
enum Color
{
    COLOR_BLACK = -1,  // -1에 대응
    COLOR_RED = -3,  // -3에 대응
    COLOR_BLUE = -4,  // -4에 대응
    COLOR_GREEN = -7,  // -7에 대응
};
  • 값을 하나만 지정해주면 그 다음 키워드들은 +1 되가는 식으로 자동으로 정의된다.
    ο 아래와 같이 3 하나만 지정해줘도 밑에는 알아서 4, 5, 6으로 정의됨.
enum Color
{
    COLOR_BLACK = 3,  // 3에 대응
    COLOR_RED,  // 4에 대응
    COLOR_BLUE,  // 5에 대응
    COLOR_GREEN,  // 6에 대응
};
  • 단 같은 정수로 대응시키면 오류
    ο 3을 가진 Color 값이 2개일 순 없어. 구분할 수 없어지니까.
enum Color
{
    COLOR_BLACK = 3,  
    COLOR_RED = 3, // 오류 !!! 
    COLOR_BLUE,  
    COLOR_GREEN,  
};
  • 쉼표로 구분하며 끝에 중괄호 다음에 세미콜론  꼭 붙여주기


주의할 점

1. 전역처럼 작동하기 때문에 서로 다른 enum 영역이라도 변수명이 같으면 오류가 난다.
   영역내에서 동일한 변수 선언 불가능

enum Feeling
{
    BLUE = -3,  
    HAPPLY = -4, 
};

enum Color
{
    BLUE, // 오류 !! BLUE는 emotion `enum`에 이미 존재. 동일한 변수 선언 불가
    RED,
};

2. enum으로 지정한 자료형 타입의 변수에 직접 정수를 대입하는건 안된다.

int color_id = COLOR_RED;  // 이건 된다. 정수 -3 color_id 에 들어가게 됨
Color my_red = -3; // 오류 !! 이건 안된다. 
Color my_red = color_id; // 오류 !! 이건 안된다. color_id 값은 int로서 -3이기 때문

       ο int color_id = COLOR_RED;
           ■ COLOR_RED 는 정수로 -3의 값으로 정의했으므로 int에 대입하는게 가능
           ■ color_id에 int로서의 -3이 저장된다.
       ο Color my_red = -3;
           ■ -3은 int고 아무리 enum이 내부적으론 정수로 저장된다고 하지만
           ■ my_red는 Color자료형이기 때문에 타입이 맞지 않아 에러가 난다.
       ο 자동으로 암시적 형변환 해주지 않음
       ο 강제로 명시적 형변환 해주면 가능하긴 하다.
           ■ -3 이 Color로 형변환되면 그에 대응되는 COLOR_RED 가 된다.

Color my_red = static_cast<Color>(-3); // -3을 Color로 형변환

3. 초기화 값을 직접 입력 받을 수 없다.

Color my_color;

cin >> my_color // 에러 ! 

int input;
cin >> input;

if (input == 0) my_color= COLOR_BLACK;
else if (input == 1) my_color = COLOR_PINK;
  • 직접 사용자 지정 자료형인 Color 타입 변수 my_color에 입력할 순 없고
  • int 에 입력받아 이가 0이면 Color 타입의 데이터값인 COLOR_BLACK; 을 대입하고
  • 이런식으로 우회해서 입력해야함.

 

 

열거형 클래스 $($영역 제한 열거형$)$

 

  •  enum class 
    ο C++ 11 이상부터 사용 가능하다.


열거형 클래스를 사용할 때

int main()
{
    enum Color
    {
        RED,
        BLUE
    };

    enum Fruit
    {
        BANANA,
        APPLE,
    };

    Color color = RED;
    Fruit fruit = BANANA;

    if (color == fruit)
    	cout << "Color is fruit ? " << endl;
    // 내부적으로 0으로 들어가기 때문에 같은 값으로 보임
}
  •  if $($color == fruit$)$ 
    ο 둘이 자료형과 영역이 다름에도 불구하고 내부적으로 정수 0의 값을 가지기 때문에
    ο 비교가 가능하다. 이 if문의 조건은 true임.
    ο 이를 막기위해 영역을 좀 더 엄격히 구분지어 제한하는게  열거형 클래스 
enum class Color
{
    RED,
    BLUE
};

enum class Fruit
{
    BANANA,
    APPLE,
};

Color color = Color::RED;
Fruit fruit = Fruit::BANANA;
  • 이제 Color::RED 와 Fruit::BANANA 는 0이라는 같은 값을 가지지만 비교할 수 없다.
  • int로 강제 형변환 하면 비교가 가능하긴 함
Color color = Color::RED;
Fruit fruit = Fruit::BANANA;

if (static_cast<int>(color) == static_cast<int>(fruit))
	cout << "Color is fruit " << endl;
728x90
300x250
LIST