IT박스

클래스 내에서 열거 형 선언

itboxs 2020. 6. 22. 08:07
반응형

클래스 내에서 열거 형 선언


다음 코드 스 니펫에서 Color열거 형 Car의 범위를 제한하고 전역 네임 스페이스를 "폴링"하지 않도록하기 위해 클래스 에서 열거 형이 선언됩니다 .

class Car
{
public:

   enum Color
   {
      RED,
      BLUE,
      WHITE
   };

   void SetColor( Car::Color color )
   {
      _color = color;
   }

   Car::Color GetColor() const
   {
      return _color;
   }

private:

   Car::Color _color;

};

(1) 이것이 Color열거 의 범위를 제한하는 좋은 방법 입니까? 아니면 Car클래스 외부에서 선언해야 하지만 자체 네임 스페이스 또는 구조체 내에서 선언해야 합니까? 나는 오늘이 기사를 보았습니다.이 기사는 후자를 옹호하고 열거 형에 대한 몇 가지 좋은 점을 논의합니다 : http://gamesfromwithin.com/stupid-c-tricks-2-better-enums .

작업 할 때이 예에서 (2) 내에서 클래스, 그것은뿐만 코드에 가장 열거입니다 Car::Color, 아니면 그냥 것 Color충분? ( Color글로벌 네임 스페이스에 선언 된 또 다른 열거 형 이있는 경우를 대비하여 전자가 더 낫다고 가정합니다 . 적어도 우리는 참조하는 열거 형에 대해 명시 적입니다.)


  1. 경우 Color단지에 특정 뭔가 Car당신이 그 범위를 제한 할 방법입니다 그 후들. Color다른 클래스가 사용하는 다른 열거 형을 사용하려는 경우 전역 또는 적어도 외부로 만들 수도 있습니다 Car.

  2. 차이가 없습니다. 전역이있는 경우 현재 범위에 가까워 지므로 여전히 로컬이 사용됩니다. 클래스 정의 외부에서 해당 함수를 정의 Car::Color하면 함수의 인터페이스에서 명시 적으로 지정해야합니다 .


요즘-C ++ 11을 사용하여 이것을 위해 enum 클래스사용할 수 있습니다 .

enum class Color { RED, BLUE, WHITE };

AFAII 이것은 정확히 당신이 원하는 것을합니다.


나는 다음과 같은 접근 방식을 선호합니다 (아래 코드). "네임 스페이스 오염"문제를 해결하지만 훨씬 안전합니다 (두 개의 다른 열거 형을 할당하거나 비교할 수 없으며 다른 내장형과 같은 열거 형도 비교할 수 없습니다).

struct Color
{
    enum Type
    {
        Red, Green, Black
    };
    Type t_;
    Color(Type t) : t_(t) {}
    operator Type () const {return t_;}
private:
   //prevent automatic conversion for any other built-in types such as bool, int, etc
   template<typename T>
    operator T () const;
};

용법:

Color c = Color::Red;
switch(c)
{
   case Color::Red:
     //некоторый код
   break;
}
Color2 c2 = Color2::Green;
c2 = c; //error
c2 = 3; //error
if (c2 == Color::Red ) {} //error
If (c2) {} error

사용법을 쉽게하기 위해 매크로를 만듭니다.

#define DEFINE_SIMPLE_ENUM(EnumName, seq) \
struct EnumName {\
   enum type \
   { \
      BOOST_PP_SEQ_FOR_EACH_I(DEFINE_SIMPLE_ENUM_VAL, EnumName, seq)\
   }; \
   type v; \
   EnumName(type v) : v(v) {} \
   operator type() const {return v;} \
private: \
    template<typename T> \
    operator T () const;};\

#define DEFINE_SIMPLE_ENUM_VAL(r, data, i, record) \
    BOOST_PP_TUPLE_ELEM(2, 0, record) = BOOST_PP_TUPLE_ELEM(2, 1, record),

용법:

DEFINE_SIMPLE_ENUM(Color,
             ((Red, 1))
             ((Green, 3))
             )

일부 참고 문헌 :

  1. Herb Sutter, 점 Hyslop, C / C ++ 사용자 저널, 22 (5), 2004 년 5 월
  2. Herb Sutter, David E. Miller, Bjarne Stroustrup Strongly Typed Enums (revision 3), July 2007

In general, I always put my enums in a struct. I have seen several guidelines including "prefixing".

enum Color
{
  Clr_Red,
  Clr_Yellow,
  Clr_Blue,
};

Always thought this looked more like C guidelines than C++ ones (for one because of the abbreviation and also because of the namespaces in C++).

So to limit the scope we now have two alternatives:

  • namespaces
  • structs/classes

I personally tend to use a struct because it can be used as parameters for template programming while a namespace cannot be manipulated.

Examples of manipulation include:

template <class T>
size_t number() { /**/ }

which returns the number of elements of enum inside the struct T :)


If you are creating a code library, then I would use namespace. However, you can still only have one Color enum inside that namespace. If you need an enum that might use a common name, but might have different constants for different classes, use your approach.

참고URL : https://stackoverflow.com/questions/2503807/declaring-an-enum-within-a-class

반응형