2012年3月17日 星期六

封裝函式樣板

利用抽象繼承+成員函式指標+樣板可以達到這樣的實作。









先實作抽象類別,保留run()這個介面。

class haFunction
{
    private:

    public:

        virtual void run() = 0;

        haFunction()
        {

        }
};


實作繼承子類別的樣板原型,在這裡以一個參數的成員函式做範例:

template <typename TC ,
typename TA1 ,
typename TR = void>
class haMemFuncPtr1 : public haFunction
{
    typedef TR (TC::*funcType)(TA1);

    private:

        funcType _memfuncPtr;

        TC *_obj;

        TA1 _a1;

    public:

        haMemFuncPtr1(funcType memfuncPtr,TC *obj,TA1 a1)
        {
            _memfuncPtr = memfuncPtr;
            _obj = obj;
            _a1 = a1;
        }

        virtual void run()
        {
            (_obj->*_memfuncPtr)(_a1); 
        }
};

再建立一個類別來封裝成員函式:

class haBind
{

    private:
        haFunction *_funcPtr;

    public:

        template <typename TC ,
        typename TA1 ,
        typename TR = void>
        haBind(TR (TC::*funcPtr)(TA1),TC *obj,TA1 a1)
        {
            typedef haMemFuncPtr1<TC,TA1,TR> bindFunc;

            bindFunc *newFunc = new bindFunc(funcPtr,obj,a1);

            _funcPtr = (haFunction *)newFunc;
        }

        ~haBind()
        {
            delete _funcPtr;
        }

        template<typename T = void>
        void operator() ()
        {
            _funcPtr->run();
        }

};


這樣我們所需要的工具就完成了

至於要怎麼使用呢?

class myObj
{
    public:

        void func(int a)
        {
            cout << a << endl;
            return;
        }

};

int main(int argc,char *argv[])
{

    myObj obj;    haBind func = haBind(&myObj::func,&obj,10);

    func();
}


這樣就能將成員函式封裝在類別中了,免去了型態的問題,
其他數量的參數也可以實現。

boost函式庫也有這樣的bind類別可供使用
算是對boost有更進一步的了解了


沒有留言:

張貼留言

Related Posts Plugin for WordPress, Blogger...