c++コールバック実装

6117 ワード

コールバックは、Aが1つの関数ポインタをBに渡し、Bを呼び出し、Bが自身の関数を実行した後、適切な時にAのこの関数ポインタを実行することで、AとBの相互包含とリンクを避けることができ、大規模なプロジェクトではループ依存を破る一般的な技術である.
 
typedef void(CALLBACK* MyCallBack)(const char *);

typedef void(*MyFuncB)(MyCallBack, const char *);



//    

void CALLBACK FuncC(const char* pszStr)

{

    std::cout << "FunC is Running" << std::endl;

    if (!pszStr)

    {

        return;

    }

    std::cout << pszStr << std::endl;

}



//    ,    FuncB

void FuncA(MyFuncB pFunB, MyCallBack pCallBAck, const char * pszStr)

{

    std::cout << "FunA is Running" << std::endl;

    if (pCallBAck && pFunB)

    {

        pFunB(pCallBAck, pszStr);

    }

}



void FunB(MyCallBack pCallBAck, const char * pszStr)

{

    std::cout << "FunB is Running" << std::endl;

    if (pCallBAck)

    {

        pCallBAck(pszStr);

    }

}



void FuncD(void)

{

    std::cout << "FunD is Running" << std::endl;

}



class  CTestA

{

public:

    void SetCallBack(MyCallBack pCallBack,const char* pszStr)

    {

        std::cout << "SetCallBack" << std::endl;

        if (pCallBack && pszStr)

        {

            m_pCallBack = pCallBack;

            m_pszStr = (char*)pszStr;

        }

        DoCallBack();

    }



    void DoCallBack()

    {

        std::cout << "DoCallBack Running" << std::endl;

        if (m_pCallBack)

        {

            m_pCallBack(m_pszStr);

        }

    }



private:

    MyCallBack m_pCallBack;

    char* m_pszStr;

};



class CTestB

{

public:

    void static CALLBACK FuncCallBack(const char* pszStr)//  static    

    {

        if (pszStr)

        {

            std::cout << pszStr << std::endl;

        }

         

    }

};





int _tmain(int argc, _TCHAR* argv[])

{

    FuncA(FunB, FuncC,"hello");

    FuncD();



    CTestA a;

    a.SetCallBack(CTestB::FuncCallBack, "hello");



    return 0;

}

boost::bindでも同様の機能を実現