enum class?
- enum class는 C++11에서 enum 자료형의 단점을 보안하기 위해 도입된 것이다.
- enum의 문제점은 enum은 별도의 이름공간(namespace)를 가지고 있지 않는 것
- 간단히 이야기하면 enum 들을 정확하게 구분하기 위해서 enum class가 도입된 것
기존 enum의 문법
#include<iostream>
using namespace std;
enum ECar{
BMW,
AUDI,
KIA,
BENZ,
HYUNDAE,
PORSCHE,
};
enum EKoreaCar{
KIA,
HYUNDAE,
};
int main(void)
{
int num = KIA; //error
cout << "KIA : " << num << endl;
return 0;
}
- KIA, HYUNDAE 처럼 열거자 이름들이 중복 되는 경우들이 있을 수 있다.
- 이런경우 컴파일러가 ECar의 KIA인지 EKoreaCar의 KIA인지 알 수가 없다.
- 결론적으로 기존의 enum은 저런식으로 enum의 열거자 이름들을 중복해서 사용할 수 없다.
enum의 이름이 중복되지 않게 접두, 접미를 넣어서 사용
#include<iostream>
using namespace std;
enum ECar{
cBMW,
cAUDI,
cKIA,
cBENZ,
cHYUNDAE,
cPORSCHE,
};
enum EKoreaCar{
kcKIA,
kcHYUNDAE,
};
int main(void)
{
int num = cKIA;
cout << "KIA : " << num << endl;
return 0;
}
이름이 중복되는 enum이 생길경우 별도의 namespace를 만들어서 사용
#include<iostream>
using namespace std;
namespace TYPEA{
enum ECar{
BMW,
AUDI,
KIA,
BENZ,
HYUNDAE,
PORSCHE,
};
}
namespace TYPEB{
enum EKoreaCar{
KIA,
HYUNDAE,
};
}
int main(void)
{
int num = TYPEA::KIA;
cout << "KIA : " << num << endl;
return 0;
}
- 위에서 소개한 2가지 방식으로 enum을 구분해서 사용할 수 있다.
- 하지만 enum class가 나온 후 위 방식을 사용하지 않아도 된다.
enum class 사용법
enum class [열거형이름]
{
//..열거자..
}
- enum뒤에 class만 붙여주면 enum class를 선언할 수 있다.
- 호출 시 열거형이름::열거자의 형태로 호출할 수 있다.
enum class EColor
{
RED,
BLUE,
GREEN,
YELLOW,
}
enum class ERainbowColor
{
RED,
ORANGE,
}
// 사용법
EColor::RED
ERainbowColor::RED
- 하지만 enum class는 enum과 다르게 주의할 점이 생기게되었다.
enum class 사용 시 주의할 점
열거자 이름에 의한 중복이 없다
- enum class는 enum과 달리 enum에 이름공간을 지어준다.
- 그렇기 때문에 코드를 작성할때 좀더 편리하고 정확하게 enum을 사용할 수 있다.
타입 변환에 좀 더 까다로움
#include<iostream>
using namespace std;
enum ESubject{
MATH,
KOREAN,
ENGLISH,
};
int main(void)
{
if(KOREAN == 1) {
cout << "KOREAN is 1" << endl;
}
else {
cout << "KOREAN is not 1" << endl;
}
return 0;
}
- 기존의 enum은 int값으로 형변환 되어 위 코드와 같은 작업을 할 수 있었다.
- enum 값이 암시적으로 형변환되어 int와 비교가 가능한 것은 이점처럼 보이지만 프롤그래머에게 예상치 못한 에러를 초래할 수 있다.
- enum class를 사용하면 더이상 int 값으로 암시적 형변환이 일어나지 않는다.
#include<iostream>
using namespace std;
enum class ESubject{
MATH,
KOREAN,
ENGLISH,
};
int main(void)
{
// static_cast 를 이용해서 int 타입으로 형변환.
// 이름공간(ESubject::)을 통해서 KOREAN 에 접근합니다.
if(static_cast<int>(ESubject::KOREAN) == 1) {
cout << "KOREAN is 1" << endl;
}
else {
cout << "KOREAN is not 1" << endl;
}
return 0;
}
- enum class를 사용하면 명시적 형변환을 통해 열거자를 비교해야한다.
전방 선언 가능
- 전방선언(forward declaration)은 선언을 먼저하고 정의를 나중에 해도 된다는 것
#include<iostream>
using namespace std;
enum class ESubject : int; //전방선언
int main(void)
{
//선언한걸 사용
if(static_cast<int>(ESubject::KOREAN) == 1) {
cout << "KOREAN is 1" << endl;
}
else {
cout << "KOREAN is not 1" << endl;
}
return 0;
}
//enum class정의
enum class ESubject : int
{
MATH,
KOREAN,
ENGLISH,
};
- enum class를 선방 선언 시 데이터 타입을 지정해 주어야 한다.
- 뒤에 데이터 타입을 지정하는 것은 바탕 형식을 지정하는 것 혹은 타입 선언을 하는 것이라고 한다.
- 컴파일러가 미리 선언을 통해서 메모리를 잡고 있어야 하기 때문에 바탕형식(어떤 타입으로 enum을 사용할건지) 지정 해야한다.
출처
https://blockdmask.tistory.com/405
'C++' 카테고리의 다른 글
[C++] 구조적 바인딩 (0) | 2024.12.13 |
---|---|
[C++] 람다 함수 (1) | 2024.12.13 |
<C++> nullptr (0) | 2024.04.03 |
<C++> static_cast (0) | 2024.04.03 |
<STL> Array (0) | 2024.02.01 |