クラスメモPart1

ゲームプログラマになる前に覚えておきたい技術をやっているが、自分の力不足を認識したので、第一部から第2部に移るときに
なんかいろいろ作ったほうがいいだろうと思い、メモ。この本のライブラリを使用。

まず、動的に生成される二次元配列クラスを作る。

普通にやるとこれだけの手順を踏む必要がある。

//動的生成
int** zTest;
zTest = new int*[row];
for(int i=0;i<row;i++) {
	zTest[i] = new int[col];
}
//delete
for(int i=0;i<row;i++) {
	delete[] zTest[i];
}
delete[] zTest;

いかにも、めんどくさい。
めんどくさい理由の一つ目はクラスにしていないため、明示的にnew,deleteしなければならないこと。
クラスだと、コンストラクタ、デストラクタで自動的に呼び出されるので、new,deleteを忘れてしまうという心配をしなくて良い。

もう一つの理由は、二次元配列にしているため、コードが一次元配列の時よりもずいぶん長くなってしまうことだ。

一応、二次元配列を一次元配列に書き換える方法がある。

arr2[i][j] <----> arr1[i*col + j]

の対応を付ければいいが、いちいちコードの中にこれを書くのはめんどくさいし、可読性が落ちるだろう。バグも増える。

ということで、内部では、一次元配列で処理しつつ、実際使うときにあたかも二次元配列を動かしているかのように作るクラスを作ろう。

まず、arr2(i,j)の形で処理できるようにしたい。
また、動的生成なので、new,deleteをコンストラクタ、デストラクタに書かねばならない。
//Array2D.h
#ifndef INCLUDED_ARRAY2D_H__
#define INCLUDED_ARRAY2D_H__


class Array2D {
public:
	Array2D(int i,int j);
	~Array2D();
	void Show(); //表示させる関数
	int& operator()(int i, int j); //参照つけないと、代入の時「式は変更可能な左辺値である必要があります」と出てくる。
private:
	int* mArray;
	int mRow; //行
	int mCol; //列

};


#endif
//Array2D.cpp
#include "GameLib/Framework.h"
#include "Array2D.h"
using namespace GameLib;

Array2D::Array2D(int i,int j) : mRow(i), mCol(j),mArray(0) {
	mArray = new int[mRow*mCol];
}

Array2D::~Array2D() {
	delete[] mArray;
	mArray = 0;
	
}

void Array2D::Show() {
	for(int i=0;i<mRow;i++) {
		for(int j=0;j<mCol;j++) {
			cout << this->operator()(i,j) << "a"; //呼び出されたインスタンスtestのtest(i,j)を返す。
		}
		cout << endl;
	}
}

int& Array2D::operator()(int i,int j) {
	return mArray[i*mCol+j];
	//mArray[i*mCol+j]を値戻しではなく、エイリアスをつくって、そっくりそのまま渡す。
	//書き込まれる時は、mArray[i*mCol+j]の箱に書き込まれ、
	//読み込まれる時は、mArray[i*mCol+j]の値を参照する。

}
#include "GameLib/Framework.h"
#include "Array2D.h"
using namespace GameLib;


namespace GameLib{
	void Framework::update(){
		int row = 4; int col = 5;
		Array2D test(row,col);
		for(int i=0;i<row;i++) {
			for(int j=0;j<col;j++) {
				test(i,j) = i*j;
			}
		}
		for(int i=0;i<row;i++) {
			for(int j=0;j<col;j++) {
				cout << test(i,j) << " ";
			}
			cout << endl;
		}
		test.Show();

	}
}

thisポインタは、そのクラスのインスタンス自体のポインタ
thisはポインタなので * を使えば、インスタンス自身を間接参照できる。