無名列挙子
C/C++ では定数をマクロを用いて記述するのが一般的です。
Date.h (かなり省略) |
#define SUN 0 #define MON 1 #define TUE 2 #define WED 3 #define THU 4 #define FRI 5 #define SAT 6 //日付クラス class Date { public: int year; int month; int date; //コンストラクタ int Date(int year, int month, int day); //曜の取得 int WDay() const; }; |
main.cpp |
#include <stdio.h> #include "Date.h" int main(){ Date d(2008, 6, 30); switch (d.WDay()){ case MON: case THU: printf("%04d/%02d/%02d => 燃えるゴミの日", d.year, d.month, d.day); break; case WED: printf("%04d/%02d/%02d => 燃えないゴミの日", d.year, d.month, d.day); break; default: printf("%04d/%02d/%02d => ゴミの日ではありません", d.year, d.month, d.day); break; } return 0; } |
2008/06/30 => 燃えるゴミの日 |
しかしその一方で、名前空間やスコープの制約を受けないため、識別子名の衝突が起こりやすい、という問題があります。
上の例では SUN
, MON
, ... といった名前が曜日を表す定数の識別子として利用していますが、こうした単純な名前は他の用途の識別子と重複する可能性が高くなるでしょう。
とは言え、他の機能を利用してマクロと同じ機能を実現するのは簡単ではありません。
- (1) const 変数を使う
- → コンパイル時に値が確定しない用途 (case ラベル, 静的配列のサイズ指定など) に使えない。
- (2) 列挙型 (名前付き enum) を使う
- → 組み込みの整数型からの変換が禁止されているため、算術操作の適用がしづらい。
こうした問題は、無名列挙子 (anonymous/nameless enumration) を使うことで解決できる場合があります。
Date.h (さらに省略) |
//日付クラス class Date { public: enum { SUN, MON, TUE, WED, THU, FRI, SAT, }; **** 省略 **** }; |
main.cpp |
#include <stdio.h> #include "Date.h" int main(){ Date d(2008, 6, 30); switch (d.WDay()){ case Date::MON: case Date::THU: printf("%04d/%02d/%02d => 燃えるゴミの日", d.year, d.month, d.day); break; case Date::WED: printf("%04d/%02d/%02d => 燃えないゴミの日", d.year, d.month, d.day); break; default: printf("%04d/%02d/%02d => ゴミの日ではありません", d.year, d.month, d.day); break; } return 0; } |