열거형 (Enumeration)
: 소스코드를 한 번에 빠르게 읽을 수 있는 능력을 위해 탄생
열거형이란 프로그래머가 프로그래밍을 할 때
가독성을 위해 탄생한 데이터 형태
흔히 우리가 int라고 하여 값을 줄 수 있지만
이는 굉장히 기계친화적이며, 기계친화적이라 함은 사람에게는 굉장히 불편하다는 것 이다.
열거형이란 프로그래머가 프로그램 소스 코드를 관리하기 쉽게, 읽기 쉽게 하기 위해 나온 데이터 타입으로서
기본적인 선언, 사용방법은 클래스나 구조체를 선언하고 사용할 때와 같습니다.
다만 열거형으로 주어진 자료는 숫자가 하나씩 꼬리표로 붙을 수 있으며
이 꼬리표를 활용해 여러가지 옵션값을 줄 수 있게 됩니다.
예를 들어보자면 성별이라는 속성을 1, 2로 주기보다 MALE, FEMALE 이라는 문자화된 값으로 줄 때
프로그래머가 굉장히 이해하기 편할 것입니다.
#include <cstdio> enum Day { SUNDAY=0, MONDAY, TUESDAY, WENDSDAY, THURSDAY, FRIDAY, SATURDAY // 열거형 상수 }; int main() { Day d = Day::MONDAY; // 열거형의 데이터 선언 // 내부적으로는 int처럼 돌아가지만 프로그래머가 읽을 때는 문자 형태로 읽을 수 있다, 문자 형태로 숫자를 조작 return 0; } |
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> enum Gender { // 열거형 MALE, FEMALE }; class Student { public: char name[10]; int student_no; Gender gender; Student(const char* name, int student_no, Gender gender) { // 생성자 strcpy(this->name, name); this->student_no = student_no; this->gender = gender; } void printInfo(){ printf("%s 의 학생번호는 %d 입니다. 성별은 %s 입니다.", name, student_no, gender == Gender::MALE ? "남성" : "여성"); } }; int main() { Student* student = new Student("말자", 2, Gender::FEMALE); student->printInfo(); return 0; } |
enum과 switch
enum은 내부적으로 Integer로 돌아가고 있기 때문에
switch구문과 밀접한 관계가 있다.
특정 상황에서는
enum과 switch를 활용하면 is ~else 구문에 비해
더 편하고 깔끔한 개발을 할 수 있게 된다.
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> enum Month { // enum상수에 값을 직접 하나하나 지정해서 내가 원하는 값으로 만들어 줄 수가 있다. JAN=1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC }; // JAN을 1부터 시작하고 싶어서 지정, 나머진 차례로 123456..로 자동 지정 // 아무것도 적지 않을 경우 JAN은 0부터 시작 int main() { Month m = Month::OCT; switch (m) { case Month::JAN: printf("1월입니다."); break; case Month::FEB: printf("2월입니다."); break; case Month::MAR: printf("3월입니다."); break; case Month::APR: printf("4월입니다."); break; case Month::MAY: printf("5월입니다."); break; case Month::JUN: printf("6월입니다."); break; case Month::JUL: printf("7월입니다."); break; case Month::AUG: printf("8월입니다."); break; case Month::SEP: printf("9월입니다."); break; case Month::OCT: printf("10월입니다."); break; case Month::NOV: printf("11월입니다."); break; case Month::DEC: printf("12월입니다."); break; } return 0; } |
상태를 나타내는 방법
비디오 게임은 여러가지 상태를 가질 수 있다.
예를 들면 PLAYING, PAUSED, WIN, LOSE 등 여러가지 상태가 있을 수 있고
이 상태를 나타내는 방법으로 enum을 많이 활용하게 된다.
게임 엔진은 이 상태를 지속적으로 판별해서 그에 알맞은 어떤 행동을 하게 된다.
보통 이 행동은 무한루프 내부에서 일어나게 된다.
enum의 종류
- 일반적인 enum
- 클래스 내부의 enum
- 강화된 enum class 타입의 enum
- 일반적인 enum
전역적으로 선언된 enum은 Month m = Month::OCT; 로 안쓰고
Month m = OCT; 로도 정상적 작동
-클래스 내부의 enum
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> class Calender { // 클래스 내부의 enum public: enum Month { JAN=1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC }; }; int main() { Calender::Month m = Calender::Month::OCT; // 클래스 내부에서의 전역적인 enum이라 OCT 앞 Month 생략가능 // Calender 클래스를 엮어준다. switch (m) { case Calender::Month::JAN: printf("1월입니다."); break; case Calender::Month::FEB: printf("2월입니다."); break; case Calender::Month::MAR: printf("3월입니다."); break; case Calender::Month::APR: printf("4월입니다."); break; case Calender::Month::MAY: printf("5월입니다."); break; case Calender::Month::JUN: printf("6월입니다."); break; case Calender::Month::JUL: printf("7월입니다."); break; case Calender::Month::AUG: printf("8월입니다."); break; case Calender::Month::SEP: printf("9월입니다."); break; case Calender::Month::OCT: printf("10월입니다."); break; case Calender::Month::NOV: printf("11월입니다."); break; case Calender::Month::DEC: printf("12월입니다."); break; } return 0; } |
-enum 클래스
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> enum class Month { // enum 클래스 JAN=1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC }; int main() { Month m = Month::OCT; // enum클래스는 enum상수를 가져올 때 타입 생략 불가능 onth m = OCT; 절대 안됨 switch (m) { case Month::JAN: printf("1월입니다."); break; case Month::FEB: printf("2월입니다."); break; case Month::MAR: printf("3월입니다."); break; case Month::APR: printf("4월입니다."); break; case Month::MAY: printf("5월입니다."); break; case Month::JUN: printf("6월입니다."); break; case Month::JUL: printf("7월입니다."); break; case Month::AUG: printf("8월입니다."); break; case Month::SEP: printf("9월입니다."); break; case Month::OCT: printf("10월입니다."); break; case Month::NOV: printf("11월입니다."); break; case Month::DEC: printf("12월입니다."); break; } return 0; } |
-enum 클래스에 강제 형변환하여 값을 집어넣기
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> enum class Month { // enum 클래스 JAN=1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC }; int main() { Month m = Month::OCT; int value = (int)m; // enum 클래스에서 integer로 들어갈 수 있다. // enum 클래스로 만들어진 이 변수는 int로 강제 형변환을 해줘야만 int로 값을 넣을 수 있다. switch (m) { case Month::JAN: printf("1월입니다."); break; case Month::FEB: printf("2월입니다."); break; case Month::MAR: printf("3월입니다."); break; case Month::APR: printf("4월입니다."); break; case Month::MAY: printf("5월입니다."); break; case Month::JUN: printf("6월입니다."); break; case Month::JUL: printf("7월입니다."); break; case Month::AUG: printf("8월입니다."); break; case Month::SEP: printf("9월입니다."); break; case Month::OCT: printf("10월입니다."); break; case Month::NOV: printf("11월입니다."); break; case Month::DEC: printf("12월입니다."); break; } return 0; } |
-enum 클래스를 쓰라고 컴파일러가 강제하는 이유
enum class Month { JAN=1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC }; enum class Math{ INC, DEC // enum 상수의 이름 중복이 있어도 class를 쓰면 막아준다. DEC 곂침 }; |
'C++' 카테고리의 다른 글
c++ 9 (여러개의 헤더와 소스) (0) | 2022.02.11 |
---|---|
c++ 8 (추가 개념 정리 / 피드백) (0) | 2022.02.05 |
c++ 5 (가상함수 - Java, C# 등 다른 언어의 개념 까지 ) (0) | 2022.01.16 |
c++ 4 (오버라이드 / 오버로드) (0) | 2022.01.13 |
c++ 3 (클래스 상속 / 접근지정자) (0) | 2021.09.24 |