C++ の列挙の宣言

列挙型は列挙子と呼ばれる一連の名前付き整数定数で構成されるユーザー定義型です。

CLR の列挙型の詳細についてはenum クラス を参照してください。

enum [tag] [: type] {enum-list} [declarator];   // for definition of enumerated type
enum tag declarator;   // for declaration of variable of type tag

パラメーター

  • tag
    列挙体に指定された型名。

  • type
    列挙型の基になる型の識別子。「解説」を参照してください。

  • enum-list
    列挙体に含まれている列挙子のリスト。

  • declarator
    列挙型の名前を指定する宣言リスト。詳細については、「宣言の概要」を参照してください。

解説

列挙型は値の範囲を表すするコンテキストを提供します。次の例ではトランプ セットに 4 個のスーツを含む列挙型を示します。

enum Suit { Diamonds, Hearts, Clubs, Spades };

列挙型の名前は列挙子になりますが列挙値の順序での位置に対応する値を割り当てます。既定では最初の値は 0次の 1 とおりの割り当てなどを割り当てます。列挙子の値を設定できます。

enum Suit { Diamonds = 1,
             Hearts, 
             Clubs,
             Spades };

Diamonds 列挙子の値は 1 を割り当てます。これは以降の列挙子に割り当てる値に影響します ; Hearts 値は 23 などです Clubs を割り当てます。

15 ではenum のキーワードは列挙型を宣言する必要があります。C++ ではenum のキーワードは省略できます。次に例を示します。

Suit current;          // Legal in C++ only

列挙型に基づく変数は特定の値を割り当てることができます。

Suit currentSuit = Hearts;

hand に曜日の値を割り当てると

int  myAccountNumber = 012345678;
Suit hand;

hand = myAccountNumber;

コンパイラ フラグ コンパイル時のエラーとしてこのようにします。技術的には両方の変数が整数の数ですがキャストは列挙型に int を変換する必要があります。ただし移動し整数値にキャストせずに列挙子を行うことで他の方法を示します。

myAccountNumber = hearts;

type は 識別子 の基になる型です。これは intshortまたは long の符号付きまたは符号なしバージョンなどのスカラー型でもかまいません。bool または char も使用できます。

列挙型はオブジェクトがわかっている値のセットを適切に考えられる場合に役立ちます。トランプ一連のスーツの例について考えます :

// enumeration_declarations.cpp
// compile with: /c
class Card {
public:
   enum Suit {
      Diamonds,
      Hearts,
      Clubs,
      Spades
   };

   // Declare two constructors: a default constructor,
   //  and a constructor that sets the cardinal and
   //  suit value of the new card.
   Card();
   Card( int CardInit, Suit SuitInit );

   // Get and Set functions.
   int   GetCardinal();          // Get cardinal value of card.
   int   SetCardinal();          // Set cardinal value of card.
   Suit  GetSuit();              // Get suit of card.
   void  SetSuit(Suit new_suit); // Set suit of card.
   char *NameOf();               // Get string representation of card.

private:
   Suit  suit;
   int   cardinalValue;
};

// Define a postfix increment operator for Suit.
inline Card::Suit operator++( Card::Suit &rs, int ) {
   Card::Suit oldSuit = rs;
   rs = (Card::Suit)(rs + 1);
   return oldSuit;
}

前の例では入れ子になった列挙型を含むクラスCardSuit 定義します。

型 Suit が入れ子になっているためクラス名 ()Card はパブリックの参照に明示的に使用する必要があります。メソッドでクラス名は省略できます。

Card::Suit の後置インクリメント演算子はユーザー定義のインクリメント演算子を使用せずにcurSuit をインクリメントできないため定義されます。ユーザー定義演算子の詳細については演算子のオーバーロード を参照してください。

次のコードはトランプを作成します。

Card *Deck[52];
int   j = 0;

for( Card::Suit curSuit = Card::Diamonds ; curSuit <= Card::Spades ; curSuit++ )
   for( int i = 1; i <= 13; ++i )
      Deck[j++] = new Card( i, curSuit );

NameOf のメソッドに関して次の例について考えます。

#define SIZE_OF_CARD_NAMES 20
char* Card::NameOf() {   // Get the name of a card.
   static char szName[SIZE_OF_CARD_NAMES];
   static char *Numbers[] = { 
      "1", "2", "3", "4", "5", "6", "7", "8", "9",
      "10", "Jack", "Queen", "King"
   };
   static char *Suits[] = {
      "Diamonds", "Hearts", "Clubs", "Spades" 
   };

   if( GetCardinal() < 13)
      strcpy_s( szName, SIZE_OF_CARD_NAMES, Numbers[GetCardinal()] );

   strcat_s( szName, SIZE_OF_CARD_NAMES, " of " );

   switch( GetSuit() ) {
      // Diamonds, Hearts, Clubs, and Spades do not need explicit
      //  class qualifier.
      case Diamonds:
         strcat_s( szName, SIZE_OF_CARD_NAMES , "Diamonds" );
      break;
      case Hearts:
         strcat_s( szName, SIZE_OF_CARD_NAMES , "Hearts" );
      break;
      case Clubs:
         strcat_s( szName, SIZE_OF_CARD_NAMES , "Clubs" );
      break;
      case Spades:
         strcat_s( szName, SIZE_OF_CARD_NAMES , "Spades" );
      break;
   }
   return szName;
}

列挙型は整数型です。enum の宣言で導入された識別子は定数を記述する場所で使用できます。通常最初の ID 値は 0 (前の例の Diamonds) です。この値はの次の識別子に 1 回ずつ増加します。したがってSpades の値が 3. です。

列挙子は列挙値に一意の値を持つ必要はありません。すべての列挙子の名前は定数として扱われenum 定義された範囲内で一意である必要があります。

リスト内の列挙子でも一つ目の値が既定値以外の値は初期化できます。Suit の宣言は次であると想定します :

enum Suit {
   Diamonds = 5,
   Hearts,
   Clubs = 4,
   Spades
};

次 DiamondsHeartsClubs と Spades の値は 564および 5それぞれ。5 では複数回使用されることに注意してください。

これらの列挙子の既定値は NameOf の関数の実装を簡素化します :

#define SIZE_OF_CARD_NAMES 20
char* Card::NameOf() {   // Get the name of a card. 
   static char szName[SIZE_OF_CARD_NAMES];
   static char *Numbers[] = {
      "1", "2", "3", "4", "5", "6", "7", "8", "9",
      "10", "Jack", "Queen", "King"
   };
   static char *Suits[] = {
      "Diamonds", "Hearts", "Clubs", "Spades"
   };

   if( GetCardinal() < 13)
      strcpy_s( szName, SIZE_OF_CARD_NAMES, Numbers[GetCardinal()] );

   strcat_s( szName, SIZE_OF_CARD_NAMES, " of " );
   strcat_s( szName, SIZE_OF_CARD_NAMES, Suits[GetSuit()] );
   return szName;
}

アクセサーの GetSuit により Suit の列挙型を示します。列挙型が整数型であるため配列の添字演算子の引数として使用できます。(詳細については添字演算子 を参照してください)。

参照

関連項目

C の列挙の宣言

C++ のキーワード

列挙子の名前

列挙子の定数の定義

変換、および列挙型