ObjectDeleter

昨日の、takelさんのコメントを見て、ちょっと思いついた。

template<T>
class CDeleter{
public:
    CDeleter( T&* p ){
        p = NULL;
        _p = p;
    }
    ~CDeleter(){
        if( _p != NULL ){
            delete _p;
        }
    }
private:
    CDeleter(){}
    T* _p;
};

template<T>
class CShellDeleter{
public:
    typedef void (*DeleteFunc)(IBase*);
    CShellDeleter( DeleteFunc df , T&* p ){
        p = NULL;
        _p = p;
        _df = df;
    }
    ~CShellDeleter(){
        if( _p != NULL ){
            _df( _p );
        }
    }
private:
    CShellDeleter(){}
    T* _p;
    DeleteFunc _df;
};

というテンプレートを用意しておいて、

void foo(){
    IFileMgr* pIFileMgr;
    char* pData;

    CShellDeleter<IFileMgr> sDelGuard( IFILEMGR_Release , pIFileMgr );
    CDeleter<char> pDelGuard( pData );
}

こうやって書けば、わざわざ解放処理を入れなくても(・∀・)イイ!!
しかも、NULLの初期化をやらなくてもいいので、安全性が増します。


で、更に楽をするために、こんなマクロを用意しました。

#define SHELL_GUARD( type , p ) \
    CShellDeleter<type> shell##__LINE__( GET_PVTBL(p,type)->Release , p )

#define POINTER_GUARD( type , p ) \
    CDeleter<type> pointer##__LINE__( p )

で、これを使えば、

void foo(){
    IFileMgr* pIFileMgr
    char* pData

    SHELL_GUARD( IFileMgr , pIFileMgr );
    POINTER_GUARD( char , pData );
}

わざわざ変数名を考えなくても(・∀・)イイ!!
でも同じ行に2つ書くのは勘弁してくださいorz


でも考えてみれば、こんなことにテンプレート使ってる時点で、BREWのプログラムとしてはダメかも(;´Д`)
でもvoid*にキャストするわけにはいかないしなぁ……やっぱりgotoでやることにしますorz


……というかこれほんとにコンパイル通るの?(;´Д`)
ポインタの参照とか滅多に使わないから、文法的に正しいのか非常に不安。
そもそもこの書き方でポインタはNULLに初期化されるのかどうかも……(~ヘ~;)ウーン
まあ、実際に試してみるのが一番なんですが(;´Д`)