クラスまみれのゲームプログラミング入門

2:半永久的に存在する変数・関数

 C言語では、一度用意されると、ずっと値が保持されるstatic修飾子が用意されています。

static.c
#include <stdio.h>

void Show1()
{
	int i = 0;
	printf("%d\n", i);
	i++;
}

void Show2()
{
	static int i = 0;
	printf("%d\n", i);
	i++;
}

void main()
{
	int i;
	for(i = 0; i < 10; i++) Show1();
	for(i = 0; i < 10; i++) Show2();
}

 上のプログラム例では、Show1()関数内にある変数iは通常の宣言(auto)であるため、Show1()関数の処理が終了すると、その内部にあった情報はすべて破棄されてしまい、そのため、何度Show1()を呼び出しても画面には「0」が表示されます。

 一方、Show2()関数の変数iはstatic宣言なので、関数が何度破棄されようが、変数iの値は残り続けるため、Show2()関数を呼び出すたびに値が1づつ増加していくことになります。


企業サイトや人気サイトの運用実績多数!月額1,500円の高スペックレンタルサーバーヘテムル

 このstatic宣言は、クラスの中でも行うことができ、クラス内で行われた変数や関数は、いくら一家(オブジェクト)が集合・離散しようが、staticだけはどこにも行くことなく、半永久的(プログラムが終了するまで)に最後に代入された値を保持し続けることになります。

static.cpp
#include <stdio.h>

class CObject
{
public:
	static int value;
	void Show()
	{
		//このようにクラス内で関数の処理内容を記述してもかまわない
		printf("%d\n", value);
	}
};

int CObject::value;	//static変数はどこかで実体化させる必要あり

void main()
{
	CObject *obj1 = new CObject();
	obj1->value = 100;
	obj1->Show();
	delete obj1;

	CObject *obj2 = new CObject();
	obj2->Show();
	delete obj2;

	printf("%d", CObject::value);
}

 このプログラムでは、19行目で値を代入した後、21行目で直接obj1クラスをメモリから削除したにもかかわらず、新規に作成したObj2から参照(24行目)したとき、最後に代入した「100」が表示され、さらには、そのobj2も除去しても、クラス内の「CObjectクラスのvalue」に直接アクセスして調べた結果(27行目)もやはり「100」となります。

 static宣言した関数は、クラスを作成することなくその関数へとアクセスすることができるようになります。ただし、static関数からは、static宣言されていない変数や関数へはアクセスできませんのでご注意を。

static2.cpp
#include <stdio.h>

class CObject
{
public:
	static int value;
	static void Show()
	{
		printf("%d\n", value);
	}
};

int CObject::value;	//static変数はどこかで実体化させる必要あり

void main()
{
	CObject::value = 150;
	CObject::Show();
}

 この手法を使えば、externを使うことなく、クラスやファイルをまたいで同一の値を保持し続けることができるので、DirectXハンドラなど、プログラムを始終通じてアクセスし続ける必要のあるデータを管理しやすくなります。