C++の列挙型(enum)を完全解説!データを分かりやすく整理するコツ
生徒
「先生、信号の色をプログラムで表したいとき、0は赤、1は青って数字で決めるしかないんですか?」
先生
「それでも動きますが、後で見返した時に『1って何色だっけ?』と混乱してしまいますよね。そんな時に便利なのが『列挙型(れっきょがた)』です。」
生徒
「れっきょがた……?なんだか難しそうな名前ですね。」
先生
「名前に数字を割り当てて、言葉として扱えるようにする仕組みですよ。C++では enum と書きます。一緒に詳しく見ていきましょう!」
1. 列挙型(enum)とは?
C++の列挙型(れっきょがた)とは、関連する「名前」を一つのグループにまとめて、新しいデータ型として定義する機能です。英語では enumeration と言い、省略して enum(イーナム)と呼びます。
プログラミング未経験の方に分かりやすく例えると、これは「オリジナルの選択肢リスト」を作る作業です。例えば、「曜日」や「トランプのマーク」「ゲームの難易度」のように、あらかじめ決まった数個の選択肢の中から一つを選ばせたい場合に非常に役立ちます。数字だけで管理するよりも、プログラムの内容が格段に読みやすくなるのが最大のメリットです。
2. 列挙型を使うメリット:読みやすさとミス防止
なぜ数字(int型)ではなく列挙型を使うのでしょうか?主な理由は2つあります。
- プログラムの可読性(かどくせい)が上がる: 「可読性」とは、人間がプログラムを読んだ時の分かりやすさのことです。
if (color == 0)と書くよりも、if (color == Color::Red)と書いたほうが、誰が見ても一目で意味が伝わります。 - 間違いを減らせる: 数字で管理していると、うっかり信号の色に「99」という存在しない数字を入れてしまうかもしれません。列挙型を使えば、あらかじめ決めた選択肢以外が入らないように制限をかけることができます。
パソコンを初めて触る方でも、スマートフォンの設定画面にある「オン/オフ」や「言語選択」のメニューを想像してみてください。あれも内部的には列挙型のような仕組みで整理されているんですよ。
3. 基本的なenumの書き方
まずは、最もシンプルな列挙型の書き方を見てみましょう。ここでは「信号の色」を例にします。
enum TrafficLight {
Red, // 0
Yellow, // 1
Blue // 2
};
int main() {
TrafficLight signal = Red;
if (signal == Red) {
std::cout << "止まれ!" << std::endl;
}
return 0;
}
このように書くと、内部では Red には 0、Yellow には 1 という風に自動的に数字が割り当てられます。しかし、使う人は数字を意識せず、「名前」だけで操作できるようになります。
4. 進化した「enum class」を使おう
C++には、古い enum の弱点を克服した enum class(列挙クラス) という強力な道具があります。今のプログラミング現場では、こちらを使うのが一般的です。
古い enum では、別のグループで同じ名前(例えば、信号の「赤」と、リンゴの「赤」)を使うと名前がぶつかってエラーになることがありました。enum class を使えば、グループ名をつけて管理するため、名前の衝突を防げます。
enum class Signal { Red, Yellow, Green };
enum class Apple { Red, Green };
int main() {
Signal s = Signal::Red; // SignalグループのRed
Apple a = Apple::Red; // AppleグループのRed
// これなら名前が同じでも間違えない!
return 0;
}
5. 列挙型に好きな数字を割り当てる
列挙型はデフォルトでは0から順番に数字がつきますが、自分で好きな数字を指定することもできます。これは、他のシステムとデータをやり取りする時などに便利です。
enum class ErrorCode {
NotFound = 404,
InternalError = 500,
Success = 200
};
このように書けば、意味のある数字と名前をセットにして保存できます。「404って何だっけ?」と検索する手間が省けるわけです。
6. 制御構文 switch文との相性が抜群!
列挙型は、条件によって処理を分ける switch(スイッチ)文と一緒に使うと非常に強力です。選択肢が全て列挙されているので、漏れなく処理を書くことができます。
enum class State { Start, Playing, GameOver };
void checkState(State current) {
switch (current) {
case State::Start:
std::cout << "ゲームを開始します" << std::endl;
break;
case State::Playing:
std::cout << "プレイ中です" << std::endl;
break;
case State::GameOver:
std::cout << "ゲームオーバーです" << std::endl;
break;
}
}
この書き方をすると、もし新しい状態(例えば「ポーズ中」)を追加した時に、処理を書き忘れているとコンピュータが教えてくれることもあります。安全なプログラムを作るための知恵ですね。
7. 列挙型を使う時の注意点:型の厳密さ
enum class を使う場合、普通の数字(int)と直接計算したり比較したりすることはできません。これは「信号の色」と「リンゴの数」を足し算しても意味がないのと同じです。もしどうしても数字として扱いたい場合は、static_cast(キャスト)という特殊な変換操作が必要になります。
最初は少し面倒に感じるかもしれませんが、この「厳密さ」こそが、大きなシステムを作った時にバグを防ぐ盾になってくれるのです。初心者のうちは、「列挙型は数字ではなく、独立した選択肢なんだ」と考えておけば間違いありません。
8. 実例:ゲームの難易度設定を作ってみよう
最後に、実際の開発でよく使われるような「難易度設定」のプログラムを作ってみましょう。これまで学んだ enum class の知識がギュッと詰まっています。
#include <iostream>
enum class Difficulty {
Easy,
Normal,
Hard
};
int main() {
Difficulty setting = Difficulty::Normal;
std::cout << "現在の難易度設定を確認します。" << std::endl;
if (setting == Difficulty::Easy) {
std::cout << "初心者向けモードです。" << std::endl;
} else if (setting == Difficulty::Hard) {
std::cout << "上級者向けモードです。敵が強くなります。" << std::endl;
} else {
std::cout << "標準的なモードです。" << std::endl;
}
return 0;
}
実行結果は以下のようになります。
現在の難易度設定を確認します。
標準的なモードです。
9. 列挙型を使いこなすためのステップ
列挙型をマスターするための近道は、自分で「選択肢」を探してみることです。「RPGの職業」「魔法の属性」「カレンダーの月」……身の回りには列挙型で表せるものが溢れています。それらを enum class で定義してみるだけで、あなたのC++のスキルは一段階アップします。
まずは小さなリストから作ってみて、プログラムが「言葉」で動く楽しさを体感してくださいね。データ型の基礎を固めることは、将来より高度なクラスやオブジェクトを学ぶ時の大きな助けになります。