ゲームが作れるようになるまでがんばる日記

ゲーム制作のことを中心にゲームに関することを書いています

C++

std::string には split が無い

最近、paizaのスキルチェック問題で文字列処理をC#で書いていたので、久しぶりにC++で書こうとしてけっこう戸惑った。 ある文字列を特定の文字で区切って分割するという処理で、C#ならば、String.Splitメソッドで簡単に書ける。 string s = "test1-test2-tes…

mapで存在確認

std::mapを使って、キーがあるかどうかの判定に[]演算子を使ってしまうと、新たにキーが作成されてしまう。 std::map<int, int> data; if(data[0]) { // ここで新たにキーが作成される } キーがあるかどうかの判定にはmapはキーが重複しないので、count()が使える。 st</int,>…

FLT_MINとFLT_MAX

C++

FLT_MIN float の正の正規化数のうち最小のものを表すマクロ。 FLT_MAX float の最大の有限値を表すマクロ。 FLT_MIN - cpprefjp C++日本語リファレンス FLT_MAX - cpprefjp C++日本語リファレンス 数多くのデータの中から、最大の値を求めようとして、まず…

インナークラスでテンプレート

C++

あるクラスをテンプレート関数で呼び出して、さらにクラスの中にあるインナークラスをテンプレートで呼び出そうとして、ちょっとハマった。 テンプレート関数のなかでさらにインナークラスを呼び出すときにはtypenameが必要となる。これに気が付かずビルドエ…

Iteratorを回す

C++

vectorなどのコンテナの要素すべてに何らかの処理を行う場合にwhile文を使うことがある。 この場合、自分はIteratorのインクリメントを忘れて無限ループに入ってしまうというミスをたびたび起こしてしまう。 std::vector<int> v; std::vector<int>::iterator itr; itr </int></int>…

range-based for

C++

配列やコンテナ内のすべての要素に対して処理を行なうfor文をrange-based for(範囲for文)と言う。 std::vector<int> test; for( auto value : test ) { cout << value; } 便利なので覚えてからは良く使うようになったのだが、コンテナ内の特定の条件を満たす要素</int>…

for文で列挙型

for文で列挙型を使うとき、autoを使うと簡単に記述することができる。 たとえば、1週間を定義したenumがあるとき、月水金だけループで実行したい場合は次のように書ける。 enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat}; for(auto day : { Days::Mon, Days…

enum class

スコープを持つ列挙型 - cpprefjp C++日本語リファレンス C++11から、列挙型としてenum classが利用できる。 スコープを持つ列挙型となり、さらに整数型への暗黙の型変換が行われない。 enum class Color { Red, Green, Blue }; Color value = Color::Red; …

#error

C++のコードで#errorと書けば、コンパイル時にエラーを発生させることが出来る。 たとえば、TESTが定義されているときにはコンパイルエラーとしたい場合は次のようになる。 #ifdef TEST #error can't build #endif#errorの後に文字列を書いておくとエラーの…

warning LNK4042

Visual Studioでプロジェクトをビルドしようとしたら、リンクのときに次のようなエラーが。 warning LNK4042: オブジェクトの指定が重複しています。余分なものは無視されます。 以前作ったクラスを改良して別のクラスへと変更し、同じ名前だけどnamespaceは…

placement new(配置new)

C++

ゲームプログラマになる前に覚えておきたい技術で初めて知ったメモリ確保の方法。 まず、operator new()という関数で指定したサイズのメモリを確保できる。 char* memory = operator new( sizeof(char) * 10 ); placement newはその指定したメモリアドレスに…

istringstreamその2

C++

istringstreamはC言語でのsscanf()のような使い方もできる。 例えば、"123,456,789"という文字列からカンマで区切られた数字を取得するには次のようにすれば良い。 #include <iostream> #include <sstream> using namespace std; int main() { string test("123,456,789"); istr</sstream></iostream>…

istringstream

C++

C++標準ライブラリにあるistringstreamはatoi()やatof()の代わりに使うことができる。文字列としてstringを使っているならこちらのほうが便利かも。 使い方はistringstreamをstringを引数にして作成し、そこから>>演算子で変換することができる。 #include <iostream> </iostream>…

オブジェクトの型を取得

C++

ある親クラスを継承した子クラスが複数種類あり、それらのオブジェクトを親クラスのポインタで保持している場合、元のオブジェクトの型を取得するときにはtypeid演算子を使えばよい。 typeid演算子はconst type_info&を返す。このtype_infoはクラスで定義さ…

メモリリークした場所にブレークポイント

メモリリークしたメモリを作成している所がいろいろな場所から呼び出されているようなとき、それがどこから呼び出されたものか知りたいときは_CrtSetBreakAlloc関数を使えば良い。 Download Visual Studio 2005 Retired documentation from Official Microso…

メモリリークの場所をわかりやすくする

Visual Studioで_CrtDumpMemoryLeaks関数を呼べば、メモリリークを検出してダンプしてくれる。さらに次のようにしてnewを呼び出すことによって、そのメモリを確保したソースの場所を表示してくれる。 #define new new(_NORMAL_BLOCK, __FILE__, __LINE__) 例…

メモリリークを発見する

Visual StudioでC++を使ってコードを書いているとき、メモリリークを見つける便利なデバッグ機能がある。 Download Visual Studio 2005 Retired documentation from Official Microsoft Download Center プログラムの終了時に_CrtDumpMemoryLeaks関数を呼べ…

strcpy_s,wcscpy_sの第2引数に指定するバッファサイズ

http://ch.cri-mw.co.jp/hirase/55242.html Download Visual Studio 2005 Retired documentation from Official Microsoft Download Center strcpyのセキュリティ強化版のstrcpy_sは第2引数にコピー先のバッファサイズを指定するようになっている。ここにsiz…

キャスト

C++

C++のキャストのまとめ。 static_cast intやfloatなどの変換に使うキャスト。型変換が行われる。Cでのキャストと同じようなもの。 reinterpret_cast 単なる型変更のキャスト。型変換は行われない。ポインタと整数を変換するとか、ある型のポインタから別の型…

参照

相変わらず本(ゲームプログラマになる前に覚えておきたい技術)を読みながら勉強中。 今回は参照の話。自分はconstと参照が苦手でどうもうまく使えていない。なんとなく知識として理解しているつもりなんだけど実際に使うときになると戸惑ってしまう。結局、…

列挙型を添え字に使う

C++

列挙型は単なるintなので添え字に使える。 enum Object { OBJ_NONE, OBJ_PLAYER, OBJ_ENEMY, OBJ_ITEM, OBJ_MAX }; Object obj[10]; const char* name[] = { "NONE","PLAYER","ENEMY","ITEM" }; for(int i=0; i<10; i++) { Object o = obj[i]; cout << name[…

列挙型のnew

C++

列挙型も型なのでnewすることができる。 enum Object { OBJ_NONE, OBJ_PLAYER, OBJ_ENEMY, OBJ_ITEM, OBJ_MAX }; Object* obj = new Object[ 100 ]; 自分は列挙型はよく状態を表すのに用い、switch文で分岐するのに使うことが多い。今まで列挙型をnewして使…

ターミナルでコンパイル

macのターミナル上でC++のソースファイルをgccでコンパイルしようとしたら、コンパイルのみは出来たがリンクの時点でライブラリが見つからずにエラーになってしまう。 原因が分からずいろいろと調べていたが、単純なミスだった。 C++のソースをコンパイルす…

変数の定義は可能な限り先延ばし

Effective C++ 第5章26項 コンストラクタやデストラクタを持つオブジェクトの変数を定義すると、生成や破棄するときにコストがかかる。なので、変数の定義は使われる直前で定義しようという話。 さらにループ内で使われる変数をループの外で定義するのが良い…

swap,min,max

C++

C++の標準ライブラリには値を交換するswap,値の小さいほうを得るmin,値の大きいほうを得るmaxが用意されている。 swap - C++ Reference min - C++ Reference max - C++ Reference #include <iostream> using namespace std; int main(int argc, char** argv) { int a =</iostream>…

暗黙の型変換

Effective C++ 第4章24項 関数を呼び出すオブジェクト(thisの指し示すオブジェクト)が暗黙の型変換で生成されることはない。そのような場合にも暗黙の型変換を利用したいなら、その関数を非メンバ関数にしよう。 本に載っているサンプルコードではoperatorを…

メンバ関数より、メンバでもfriendでもない関数を使う

Effective C++ 第4章23項 メンバ関数より、メンバでもfriendでもない関数を使おう。それによって、カプセル化の度合いを増し、柔軟性と機能拡張性を持たせることになる。 これはまだ読んでもいまいちしっくりきていない。 本を読みながら、自分なりにサンプ…

データメンバはprivateに

Effective C++ 第4章22項 クラスのデータメンバはprivate宣言するというのは当然。もちろんこれはカプセル化のため。カプセル化しておけば、中身の実装方法を変更してもそのオブジェクトを使う側は変更する必要がない。これは複数人で協力してコードを書くよ…

オブジェクトを戻すときに参照で戻すな

Effective C++ 第4章21項 値渡しよりも参照渡しのほうが効率が良いからといって、ある関数での戻り値をすべて参照にすればいいわけではない。クラスのメンバ変数なら関数を抜けたあとも存在しているから良いが、ローカル変数の場合は関数を抜けると破棄され…

const参照渡し

久しぶりにEffective C++を読みながら勉強の再開。第4章20項。 関数にオブジェクトを渡すときは値渡しよりもconst参照渡しを使うほうが良い。値渡しではオブジェクトのコピーが行われるためコンストラクタやデストラクタが実行されることになる。const参照渡…