===== 名前空間の使い方 ===== {{url>https://replit.com/@youetsusato/namespace?v=1&embed=true#main.cpp 700, 900}} ===== ついでにenumの話 ===== 通常のenumの使い方(Cのenum)\\ #include //画像ファイルの色を表したいenum enum Colors { RED = 0, GREEN, BLUE, ALPHA, }; //enum Renger //{ // RED, BULE, PINK, GREEN, YELLOW, //}; const int ImageWidth = 600; const int ImageHeight = 400; //画像のピクセルを表す配列(3次元怖い) unsigned char ColorImage[ImageWidth][ImageHeight][4]; int main() { //画像の色を黒で初期化 for(auto j=0;j こんな感じで、整数値として使えます。\\ これはもはや、これとほとんど同じです。\\ #define RED 0 #define GREEN 1 #define BLUE 2 #define ALPHA 3 これを、勝手にリストを作ると、初期値から1ずつ値を増やしてくれる便利な整数の定数が作れます。\\ が通常のenumになります。\\ 初期値をずらすこともできます。\\ {{:game-engineer:classes:2023:game-programing-2:first-term:5:clipboard01.png?400|}} \\ for文で使うこともできるし、switch-case文で使うこともできます。便利!\\ けど、こんなことが起こります。\\ 球にプログラムに、戦隊ものの要素を加えようと思い、こんなenumを追加します。\\ enum Renger { RED, BULE, PINK, GREEN, YELLOW, }; \\ これで、画像の色の他に、戦隊ものヒーローの色を扱うenumが。。。できない。\\ {{:game-engineer:classes:2023:game-programing-2:first-term:5:clipboard02.png?400|}} \\ 何かわかんないけど、C++の始祖であるC言語の時代からあるenumの仕組みではなんとenumの種類が違っても同じ名前のenumのメンバは作れないようです(´;ω;`)\\ ==== C++の新しいenum ==== C++は、アクセスやスコープを制限して、安全性を高める言語でしたね!\\ そんなC++に2011年のバージョンアップの時に(C++11)新しい仲間が増えました。\\ (僕が1993年にC++を習った時にはテンプレートもなかったんだぞ)\\ それが、```enum struct```(```enum class```)です。\\ これを使うと、さっきの問題が。。。\\ enum struct Colors { RED = 0, GREEN, BLUE, ALPHA, }; enum struct Renger { RED, BULE, PINK, GREEN, YELLOW, }; \\ これで、enumにスコープを付けることができて、Colors::REDと、Renger::REDは全く別のスコープに存在するので区別されるようになります。\\ 解決!。。。って思うじゃん。\\ {{:game-engineer:classes:2023:game-programing-2:first-term:5:clipboard03.png?400|}} 配列の要素指定が整数ではありません。って言われてしまいました。\\ これは困った。\\ 実は、スコープが付いたのはいいけれど、```enum class```や```enum struct```は__整数の値を持った、列挙型と言う型ですが、整数型自体とは異なる型__として扱われます。\\ Cのenumはただの整数だったので楽だったね。。。\\ 整数として使いたいときは(多分その使い方がすでに間違ってんだろね。。。)型変換を行います。\\ ColorImage[i][j][static_cast(Colors::RED)] = 0; ColorImage[i][j][static_cast(Colors::GREEN)] = 0; ColorImage[i][j][static_cast(Colors::BLUE)] = 0; ColorImage[i][j][static_cast(Colors::ALPHA)] = 255; === ちなみに === 本来は、整数値として使うのではなく、もう、この```enum class```しか受け取らないよ。と言う形での使い方が正しいです。\\ 上の、整数値のやつはスコープとしては、\\ const int RED = 0; const int GREEN = 1; const int BLUE = 2; const int ALPHA = 3; と一緒で、列挙したときに自動で値を1個ずつ増やしてくれるのが便利、なだけの使い方をしているってことになります。\\ \\ 本来は、以下の様に、enum classを使うことによって、それ以外の型は受け付けないので間違いを防ぐ、という使い方の方が正しいです。\\ #include #include enum class CardMark { spade, club, diamond, heart, }; std::string get_mark_string(CardMark card_mark) { // switch文の caseラベルに使える switch (card_mark) { case CardMark::spade: return "spade"; case CardMark::club: return "club"; case CardMark::diamond: return "diamond"; case CardMark::heart: return "heart"; default: return ""; } } int main() { CardMark mark {CardMark::spade}; // 変数の宣言と初期化 mark = CardMark::diamond; // 代入 std::cout << std::boolalpha << (mark == CardMark::diamond) << "\n"; // 比較 std::cout << get_mark_string(mark) << "\n"; }