fetus Diary

2006/12/30(土) - shard_ptr と weak_ptr による参照型 Singleton クラスの実装

前の記事はこちら

たまには真面目に書くのも良いかなぁ、とか思いまして。自分用の防備録でも有るわけですが。

#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/noncopyable.hpp>

class SingletonClass : private boost::noncopyable {
private:
  SingletonClass();
public:
  ~SingletonClass();
  static boost::shared_ptr<SingletonClass> GetInstance();
private:
  static boost::weak_ptr<SingletonClass> sm_instance;
};
#include "SingletonClass.h"

boost::weak_ptr<SingletonClass> SingletonClass::sm_instance;

SingletonClass::SingletonClass() { }

SingletonClass::~SingletonClass() { }

boost::shared_ptr<SingletonClass> SingletonClass::GetInstance() {
  boost::shared_ptr<SingletonClass> instance = sm_instance.lock();
  if(! instance) {
    // ここでマルチスレッド用排他ロックする
    instance = sm_instance.lock();
    if(! instance) { // double-checked locking pattern
      instance = boost::shared_ptr<SingletonClass>(new SingletonClass());
      sm_instance = instance;
    }
    // ここでロックを解除する
  }
  return instance;
}

ロックに関しては本質で無いので取り除いてあります。まぁ、Windows ならテキトーに Mutex でも使えば良いでしょう。

あと、コンパイル通していないので動くかどうかはわかりません。まぁ、雰囲気の問題ということにしておいてください。代入演算子とコピーコンストラクタの禁止については面倒なので boost::noncopyable にお任せしていますが、本質ではありません。別にコピー出来なければ何でも良いのです。

たぶん、こんな感じのロジックで参照カウント型の Singleton クラスができると思うのです。実際問題、これを使って何か問題が出ても知ったこっちゃぁ有りませんが。

自分が static で覚えている自分型へのポインタは weak_ptr なのがミソ。これを shared_ptr にすると永遠に参照カウントが 0 にならないので解放されません。インスタンスが解放されないことによるメモリリークについてはどうでも良いと思いますが(どうせ OS または C++ ランタイムが解放してくれる(と期待できるし、今日日の OS がその程度のリソース管理をしていないとは到底考えられない)し)、自クラスのデストラクタと自クラスのメンバ変数の解放が動かないのは問題なので、解放してやる必要があるのです。weak_ptr なら同じインスタンスを参照している shared_ptr が居なくなれば自動的に解放され、かつ、weak_ptr 自身は無効化されたのを知ることができる、ので両方の条件を満たせるのです。

と、内包型の Singleton クラスは簡単なのだけど、継承による Singleton 属性をつけるようにしようとすると、外からは構築できる必要があるが、それは Singleton クラスで無ければならない、つまり、被 Singleton クラスのコンストラクタを private にした上で Singleton<typename `被 Singleton クラス`> クラスに対して friend 指定が必要というイヤンな状態になってしまうのよね…。

関係あるかも?

このエントリは次のエントリから参照されているみたいです

  • 2006/12/27(水) - HiNa - 流用

コメント

コメントはありません。

名前
メール
コメント

※HTML タグは使えません。HTTP URL には自動リンクが張られます。

Captcha
画像から読み取れる文字を入力: