C/C++:回调的方式代码实现

/ C++ / 没有评论 / 1942浏览

回调:在字面上的意思是A对象调用B对象的成员函数,但是B对象又想调用A对象的成员函数,实际上编译器在循环包含头文件的话会报错。

注意点:所有的回调函数和回调对象都要保持有效性,就是不能够被提前释放掉。

function和bind

 这种方式就是利用C++11的语法,function有绑定的函数地址,在别的地方拿到的时候就可以直接调用了,但是在多线程中要使用小心,要保证对象的一致性。

方式代码

C的方式

C中实现的方式其实是先要注册回调函数(函数地址),然后再使用。
#include <iostream>

typedef void (__stdcall *DownloadCallback)(const char *pURL,bool OK);

void DownLoadFile(const char *pURL,DownloadCallback callback)
{

    std::cout<<"downloading..."<<pURL<<""<<std::endl;
    callback(pURL,true);
}

void __stdcall onDownloadFinished(const char* pURL,bool bOK)
{
    std::cout<<"onDownloadFinished..."<<pURL<<"   status:"<<bOK<<std::endl;
}

void main()
{
    DownLoadFile("http://wwww.baidu.com",onDownloadFinished);

    system("pause");
}

C++ 继承和多态

//多态的时候,基类指针指向子类对象,然后调用虚函数,会调用子类的实现。这样子的话就实现回调了自身的函数。
class IDownloadSink
{
public:  
    virtual void OnDownloadFinished(const char *pURL,bool bOK) = 0;
};

class CMyDownloader
{
public:  
    CMyDownloader (IDownloadSink *pSink)
        :m_pSink(pSink)
    {

    }

    void DownloadFile(const char* pURL)
    {
        std::cout<<"downloading..."<<pURL<<""<<std::endl;
        if(m_pSink!=NULL)
        {
            m_pSink->OnDownloadFinished(pURL,true);
        }
    }

private:
    IDownloadSink *m_pSink;
};


class CMyFile:public IDownloadSink
{
public:  
    void download()
    {
        CMyDownloader downloader(this);
        downloader.DownloadFile("www.baidu.com");
    }

    virtual void OnDownloadFinished(const char *pURL,bool bOK) 
    {
        std::cout<<"onDownloadFinished..."<<pURL<<"   status:"<<bOK<<std::endl;
    }
};

void main()
{
    CMyFile *file = new CMyFile();
    file->download();

    system("pause");
}

代理delegate者其他方式,其实消息队列也可以实现。主要是看代码怎么写。

注意点:多线程下!