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

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

C++

dynamic_cast演算子

C++

dynamic_cast演算子を使ったキャストでは正しくキャストできるときにはキャストを行うができないときはnullを返す。 派生クラスのオブジェクトをその親クラスのポインタで取得したとき、派生クラスへのdynamic_castを行うことによってそのオブジェクトがその…

typeid演算子その2

C++

以前、typeid演算子について学んだ(id:toburau:20071108)が、それはテンプレートクラスにも適用できる。 #include <iostream> using namespace std; template <class T> class Test { T mValue; public: Test(T n) { mValue = n; } }; int main() { Test<int> test0(123); Test<float> test1</float></int></class></iostream>…

ランダムアクセス

C++

ランダムアクセスにはseekg(),seekp()を使う。seekg()はファイルの取得ポインタを、seekp()は出力ポインタを操作する。指定するパラメータは移動させるバイト数と基準となる位置の二つ。 istream &seekg(off_type offset, seekdir origin); ostream &seekp(o…

バイナリファイルの出力

C++

バイナリファイルを出力するには、ofstreamを使えばよい。コンストラクタの第2引数にifstream::binaryを付けてストリームを作成し、write()を使う。 プログラムは次の通り。 #include <iostream> #include <fstream> using namespace std; bool writeFile( const char* name, co</fstream></iostream>…

ファイルの出力

C++

テキストファイルの出力にはofstreamを使えば簡単に行える。 ofstreamのストリームを作成し、あとはコンソールと同じように演算子で出力できる。出力し終わったあとはclose()で閉じる。 #include <iostream> #include <fstream> using namespace std; int main() { ofstream out</fstream></iostream>…

入出力マニピュレータ

C++

ストリームの書式指定を変更する方法として入出力マニピュレータを使う方法がある。これは入出力の式の中に埋め込むことのできるもの。 いくつも種類があるか、たぶん自分が使うことになるのは、16進数で入出力するhexと10進数で入出力するdecだろう。 #incl…

iosクラスのメンバ関数で書式化

C++

coutといったストリームでは書式化するためのメンバ関数や書式フラグが用意されている。 書式フラグを設定する関数はsetf()。解除する関数はunsetf()。フラグはfmtflagsという列挙型。他にもフィールド幅を設定するwidth()といったものある。 #include <iostream> usin</iostream>…

入出力演算子のオーバーロードその2

C++

今度は>>演算子。 独自クラスで入力を受け付けるプログラムは次の通り。 #include <iostream> using namespace std; class Vector { private: int x,y; public: void show() { cout << x << "," << y << endl; } friend istream &operator>>(istream &stream, Vector &</iostream>…

入出力演算子のオーバーロードその1

C++

入出力演算子とはコンソールに文字を出力したりするときにつかう>のこと。演算子は挿入演算子、>>演算子は抽出演算子ともいう。 独自に作成したクラスを #include <iostream> using namespace std; class Vector { private: int x,y; public: Vector(int a, int b) { x</iostream>…

newとdeleteのオーバーロードその2

C++

オーバーロードするnewとdeleteをクラスのメンバ関数として定義すれば、そのクラスをnewやdeleteしたときのみオーバーロードしたもので行うようにすることができる。 #include <iostream> using namespace std; class Test { public: void *operator new(size_t size);</iostream>…

newとdeleteのオーバーロード

C++

newとdeleteのオーバーロードの書き方は次の通り。メモリー割り当て、解放はmalloc()とfree()を使った。 void *operator new(size_t size) { void *p; p = malloc(size); if(!p) { bad_alloc ba; throw ba; } return p; } void operator delete(void *p) { f…

newに失敗したときNULLを返す

C++

C++でnewに失敗したときは例外が投入されるが、NULLを返すようにすることもできる。 ポインタ変数 = new(nothrow) 型;nothrowを付ければ例外ではなくNULLを返すようになる。 #include <iostream> using namespace std; void main() { int* p; for(int i=0; i<1000; i++</iostream>…

newが失敗したとき

C++

newでメモリ確保に失敗したときはbad_alloc例外が投入される。 私はてっきりNULLを返すと思っていたけど、それはC++ができた初期のころだけだったらしい。 実際に試してみたコード。 #include <iostream> using namespace std; void main() { int* p; for(int i=0; i<1</iostream>…

ASSERTで文字列を表示

ASSERTは配列の添字が範囲内に入っているかとか、渡された引数は正しいかなどのチェックに重宝する。 ASSERTでプログラムが停止されたときにはそのときの引数が表示される。そこで引数に&&を付けて文字列も指定してやれば、その文字列も表示される(文字列はt…

catchですべての例外

C++

前回はcatchで受け取る例外の型を指定したが、型を指定しないですべての例外を受け取る方法もある。 catch(...) { // 処理 } ...は省略記号。これですべてのデータ型と一致する。 #include <iostream> using namespace std; void func(int i) { if (i!=0) throw i; } v</iostream>…

try throw catch

C++

例外を使うときにはtry,throw,catchのキーワードを使う。 まず、例外を発生させる対象となるプログラムをtryブロック内に書く。例外を発生させるときはthrow文。その例外をcatch文で受け取る。 #include <iostream> using namespace std; void func(int i) { if (i!=0)</iostream>…

汎用クラスその6

C++

汎用クラスで特定の型のときのみ処理を変えた実装をすることができる。 次のプログラムではintときに違う処理を行う例。 #include <iostream> using namespace std; template <class T> class Test { T mValue; public: Test(T n) { mValue = n; } T get() { return mValue; } }</class></iostream>…

汎用クラスその5

C++

汎用クラスで指定する汎用型や非汎用型の引数でもデフォルト引数を使うことができる。 #include <iostream> using namespace std; template <class T=int, int num=10> class Test { T mValue[num]; public: Test() { for(int i=0; i<num; i++) mValue[i] = i; } T get(int i) { return mValue[i]; } }; void main() { Test<> obj; cout << obj.get(3) << endl; }</num;></class></iostream>

汎用クラスその4

C++

汎用クラスのテンプレート指定では汎用型ではない引数を指定することもできる。 ただし指定できるのは整数、ポインタ、参照のいずれか。 #include <iostream> using namespace std; template <class T, int num> class Test { T mValue[num]; public: Test() { for(int i=0; i<num; i++) mValue[i] = i; } T get(int i) { return mValue[i]; } }; void main() { Test<int, 10> obj; cout <</num;></class></iostream>…

汎用クラスその3

C++

汎用クラスでメンバ関数の実装部分での記述の仕方で戸惑ったのでメモ。 template <class T型> 返り値の型 クラス名<T型>::メンバ関数名(仮引数リスト) { ... } たとえば汎用型を返すメンバ関数の場合は次のような感じ。 #include <iostream> using namespace std; template <class T> class Test</class></iostream></t型></class>…

汎用クラスその2

C++

汎用関数と同じように複数の汎用型を指定できる。 #include <iostream> using namespace std; template <class T1, class T2> class Test { T1 mValue1; T2 mValue2; public: void set(T1 i, T2 j) { mValue1 = i; mValue2 = j; } void put() { cout << mValue1 << endl << mValue2 << endl</class></iostream>…

汎用クラス

C++

クラスで使用するアルゴリズムは同じだが、対象となるデータ型が異なるような場合は汎用クラスを用いるとよい。 汎用クラスの宣言は次の通り。 template <class T型> class クラス名 { ... } 実際にインスタンスを生成するときは クラス名 <型> オブジェクト名 となる。</class>…

汎用関数その2

C++

template文でカンマで区切ることによって複数の汎用型を定義することもできる。 #include <iostream> using namespace std; template <class T1, class T2> void func(T1 a, T2 b) { cout << a << ' ' << b << endl; } void main() { func(123, "test"); }</class></iostream>

汎用関数

C++

汎用関数とは自分自身をオーバーロードできる関数。テンプレート関数ともいう。 定義は次の通り。 template <class T型> 戻り値の型 関数名(仮引数リスト) { // 処理内容 } T型と書かれている部分が自動的に置き換わる。classと書いてあるがintやfloatといったものでも</class>…

純粋仮想関数

C++

純粋仮想関数を宣言するには次のように virtual 型 関数名(仮引数リスト) = 0; 関数名のあとに=0を付ける。 見た目はまるで関数に0を代入しているかのようだ。というよりも関数のアドレスが0、つまり定義されていないと考えればいいのかな。

仮想基本クラス

C++

#include <iostream> using namespace std; class base { public: int i; }; class derived1 : public base {}; class derived2 : public base {}; class derived3 : public derived1, public derived2 {}; int main() { derived3 test; cout << test.i; // コンパイル</iostream>…

継承したときのコンストラクタ、デストラクタ

継承したとき、コンストラクタとデストラクタが実行される順番について勉強。 いくつも継承していると順番を間違えてしまいそうだ。 多重継承したときは記述した順番で実行される。 class base1; class base2; class test : public base1, public base2 { };…

多重継承

複数のクラスを継承する多重継承について勉強中。 class base1; class base2; class Test : public base1, public base2 { }; ちゃんと設計しないまま、いくつも継承していったら、あるメンバがどこから継承されたものか分からなくなってしまいそうだ。便利…

protectedで継承

C++

昨日に引き続き、継承の勉強。今度はprotectedで継承した場合。protectedで継承すれば基本クラスのpublicとprotectedのメンバは派生クラスのprotectedメンバとなる。 #include <iostream> using namespace std; class base { public: void func() {} }; class PrivateB</iostream>…

継承

C++

クラスを継承する場合は次のように記述する。 class 派生クラス名 : アクセス 基本クラス名 { ... } アクセスはpublic, private, protectedのいずれか。 これは初めて知った。いままでいつもpublicで書いていて他のが指定できるとは思っていなかった。 priva…