参照カウンタの実装で悩み中

STATUS: 故障中

 Bitmapハンドルを管理するクラスを作ってるとこです(楽しい車輪の再発明)。

class MyBitmap {
        HBITMAP m_hbitmap;
        int m_nRefCount; // これは、ちゃんと動作しないだろう
       
        MyBitmap() {
                m_hbitmap = NULL;
                m_nRefCount = 0;
        }
        virtual ~MyBitmap() {
                Release();
        }
       
        Create( なにかパラメータ ) {
                m_hbitmap = ビットマップを生成する;
                m_nRefCount = 1;
        }
       
        void Release() {
                m_nRefCount--;
                if ( m_nRefCount==0 ) m_hbitmap開放
        }
       
        MyBitmap( MyBitmap &rbmp ) {
                m_hbitmap = rbmp.m_hbitmap;
                m_nRefCount ++;
        }
       
        MyBitmap& operator =( MyBitmap &rbmp ) {
                m_hbitmap = rbmp.m_hbitmap;
                m_nRefCount ++;
                return *this;
        }
};

 だいたい上記のようなクラスを作るつもりです。
 参照カウンタを持つことで、インスタンスをコピーとかしても正しく開放出来るようにしようという感じ。
 こういう使い方を想定しています。

MyBitmap CreateBitmap() {
        MyBitmap bmpTemp;
        bmpTemp.Create( 何かパラメータ );
        return bmpTemp;
}

MyBitmap bmp = CreateBitmap();

 利用するときはポインタを一切使わないですむので安全。の予定。

MyBitmap bmp2 = bmp;

 とかやるとメンバ変数がコピーされて参照カウントが1アップ…しないよ。
 インスタンスが別なので、m_nRefCount が同一じゃない〜(あたりまえだ)。

class MyBitmap {
        HBITMAP m_hbitmap;
        int* m_pnRefCount;
       
        MyBitmap() {
                m_hbitmap = NULL;
                m_pnRefCount = NULL;
        }
        virtual ~MyBitmap() {
                Release();
        }
       
        Create( なにかパラメータ ) {
                m_hbitmap = ビットマップを生成する;
                m_pnRefCount = new int();
        }
       
        void Release() {
                if ( m_pnRefCount ) {
                        *m_m_pnRefCount--;
                if ( *m_pnRefCount==0 ) {
                        m_hbitmap開放
                        delete m_pnRefCount;
                        m_pnRefCount = NULL;
                }
        }
       
        MyBitmap( MyBitmap &rbmp ) {
                m_hbitmap = rbmp.m_hbitmap;
                m_pnRefCount = rbmp.m_pnRefCount;
                *m_pnRefCount++;
        }
       
        MyBitmap& operator =( MyBitmap &rbmp ) {
                m_hbitmap = rbmp.m_hbitmap;
                m_pnRefCount = rbmp.m_pnRefCount;
                *m_pnRefCount++;
        }
};

 うーん。こんな感じにすればいいのかな。

 メンバ変数はもっと増えるので、コピー時のコストが心配(実際にはコピー処理はあんまり発生しないだろうけど)。
 あと、配列やコレクションに格納するとき凄い無駄がでそう…。
 (ポインタで格納したら安全化の努力が無意味になるし)

 bitmapクラス自体は普通に作って、boostのshared_ptrとか併用した方がよさそうな気がしてきた…。
 まあいいや。このまま作って、あとで効率とか問題になったらshared_ptrなりshared_arrayを使うことにしよう。

● 関連URL

COM研究室 - Chapter.6 参照カウンタと寿命
プログラミング - munepi.com
 スマートポインタの効能
 auto_ptrはダメなのか?
 weak_ptrに馳せる夢
スマートポインタ
S34
Boost C++ Libraries

コメント