Hatena::ブログ(Diary)

ゲームを作りたい! Twitter

2011-03-05

テンプレート版シングルトンクラス

今回はシングルトンの話です。

シングルトンと言えば、デザインパターンの中でも最も有名と言ってもいいぐらいのパターンですね。

http://ja.wikipedia.org/wiki/Singleton_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3

で、ほかの人や自分コードを見たらシングルトンを適用するクラスに毎回シングルトンのコードをコピペしてるんですね。

コピペするのも冗長でめんどくさいな〜と思ったので、勉強も兼ねてテンプレート版のシングルトンクラスを作成してみました。

また何かおかしな所があればコメントお願いします。


テンプレート版シングルトンクラス

多分こんな感じになるかと・・・。

template <class T>
class Singleton {
public:
	static T& getInstance(){
		static T _Instance;
		return _Instance;
	}

protected:
	Singleton(){};
	virtual ~Singleton(){};

private:
	Singleton(const T& obj);
	Singleton& operator=(const Singleton& obj);

};

通常のシングルトンクラスの場合はコンストラクタやデストラクタをprivate指定しますが、今回はprotectedに指定しています。

こうしなければ、このクラスを継承した際にコンストラクタやデストラクタが継承先から呼び出せなくなってしまうからです。

その他は特に変わった所はありません。

続いてこのクラスを継承してみましょう。

class TestManager : public Singleton<TestManager> {
	friend Singleton<TestManager>;
public:
	void draw(){
		printf("%d:%x\n", count, this);
	}
	void addCount(){
		count++;
	}

private:
	TestManager() :
	count(0){
	}
	int count;

};

上から順に説明します。

まず継承する時に"Singleton<TestManager>"としています。

これでTがSingleton型に置き換わります。

次に"Singleton<TestManager>"をフレンド指定しています。

Singleton<TestManager>::getInstance()でTestManagerのインスタンスを生成する時に、コンストラクタが呼べなかった為friend指定にしました。

あとは描画用の関数と、カウンタを上げる関数になっています。

描画関数では現在のカウンタの値と、アドレスと表示するようにしてあります。

使ってみる

これを使うとこんな感じになります。

void main(void)
{

	TestManager& manager1 = TestManager::getInstance();
	TestManager& manager2 = TestManager::getInstance();

	manager1.draw();
	manager1.addCount();
	manager2.draw();
	manager2.addCount();
	manager1.draw();

	return;
}

実行結果

0:3791b0

1:3791b0

2:3791b0

アドレスが同じで、カウンタの値も正しいですね。

こんな感じで、冗長なコードはなるべく書かないようにしたいですね。

時間も惜しいですし・・・。

「このほうがいいのでは?」とかありましたら、どしどしコメントください。

名前は開発中のものです。名前は開発中のものです。 2011/03/06 15:30 この記事を読んで、いろいろと心配になってしまいました。新しい
ゲームプログラマさんがシングルトン大好きになってしまうような環境が
まだまだあるのだなぁと。

そもそも本当にシングルトンが必要なのか?適切なのか?そこらへんは十分に
考察されているでしょうか?ただのグローバル変数の隠れ蓑として使おうと
されているのではないですか?
http://www.aerith.net/design/Singleton-j.html
http://www.google.co.jp/search?q=%22singletons+are+evil%22

必要で適切だとしても、それを(労無くクラス外変数・関数が使える) C++ で
クラステンプレートにする意味を見出されているでしょうか?
http://www.radiumsoftware.com/0309.html#030912

記事中のコードに 〜Manager が多いのも気になりました。
http://www.google.co.jp/search?q=SomethingManager

buti2112buti2112 2011/03/06 20:33 コメントありがとうございます。
URLの記事を読ませていただきました。

私のシングルトンに対する考察が足らなかったようです。
自身の勉強不足を痛感しました。

現場ではシングルトンはどのように使われているのか気になります。

まだまだ勉強不足な専門学生ですがこれからもよろしくお願いします。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/buti2112/20110305/1299354753