CとC++、C#、Javaにおけるenumの違い

注意: この記事は1年以上前に掲載されたものです。情報が古い場合がありますのでお気を付け下さい。

C言語、C++、C#、Javaではいわゆる「列挙型」としてenumが使える。しかしながら、C言語とC++、C#、Javaのenumはそれぞれ別ものである。

C言語/C++におけるenum

C言語におけるenumは実際には整数型として扱われる(列挙定数も同様)。そのため、enum型で定義された型は暗黙的に整数型と基の列挙型を相互に変換することが可能であり、enumに定義されていない値を保持することもできる。なお、このenumはスコープされないため、使い方次第では他の定数やdefineと競合を起こす可能性がある。

C++では従来の方式のenumは基本的にはC言語と同様だが、列挙定数については基となった列挙型となっている。これについては通常の整数型への暗黙的な変換は可能だが、整数を列挙型に変換する場合はキャストなどが必要になる。

C言語やC++においては、後述のスコープされたenumも含めて関数・メソッド内にローカルenumとして定義することも可能である(C#及びJavaでは不可能)。

C++におけるスコープされたenum

C++11以降ではenumとは別にスコープされたenumを使うことができる。この場合は「enum class (列挙型名)」あるいは「enum struct (列挙型名)」に始まるが、こちらは当然ながらスコープされるため、スコープされないenumと比較して名前の衝突は抑えられる。

スコープされたenumでは、列挙定数から整数型への変換の際にもキャストが必要になる。

それを除けばC++におけるスコープされていないenumとほぼ同様である。

C#におけるenum

C#におけるenumは実体としては整数として扱われる。整数への変換や列挙型への変換については双方とも可能。定義されていないenum型の値にすることも可能な点はC言語やC++とほぼ同じ。

C言語とは違い、C++11以降におけるスコープされたenumのようにスコープされる。

Javaにおけるenum

Javaにおいては実体は整数ではなく、クラスとして扱われる。

デフォルトでは定数の数値がordinalメソッド、定数名がnameメソッドで定義されており、C/C++/C#とは違い、そのまま定数にキャストすることはできない。数値に変換するにはordinalメソッドが必要。

逆に数値からenumにするには独自にメソッドを実装する必要があり、なおかつenumで定義されていない値は保持することができない。

最後に

列挙型として知られているenumだが、言語によってその実体や定義できる範囲などが違うため、一定以上の注意は必要である。とはいえ、enumを有効に使うことによって、安全かつ簡潔に処理を行うこともできるようになるので、ぜひ有効に活用したい。

タイトルとURLをコピーしました