zoukankan      html  css  js  c++  java
  • C++回调机制

    一直对回调机制不是很了解,今天索性搜了很多资料顺便整理一下,进步一点点。

    1.Callback方式(回调函数)

      什么是回调函数?

      简而言之,回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。

    typedef void (__stdcall *DownloadCallback)(const char* pURL, bool bOK);  
    void DownloadFile(const char* pURL, DownloadCallback callback)  
    {  
        cout << "downloading: " << pURL << "" << endl;  
        callback(pURL, true);  
    }  
    void __stdcall OnDownloadFinished(const char* pURL, bool bOK)  
    {  
        cout << "OnDownloadFinished, URL:" << pURL << "    status:" << bOK << endl;  
    }
    //初始化
    DownloadCallback = OnDownloadFinished;

      回调函数是继续自C语言的,因而,在C++中,应只在与C代码建立接口,或与已有的回调接口打交道时,才使用回调函数。除了上述情况,在C++中应使用虚拟方法

    2.虚拟方法

      本质是你按照对方要求实现一个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)
        {
            cout << "downloading: " << pURL << "" << 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.sina.com");
        }
    
        virtual void OnDownloadFinished(const char* pURL, bool bOK)
        {
            cout << "OnDownloadFinished, URL:" << pURL << "    status:" << bOK << endl;
        }
    };

    这里使用多态,子类指针实例化父类指针。

    父类子类指针函数调用注意事项
    1,如果以一个基础类指针指向一个衍生类对象(派生类对象),那么经由该指针只能访问基础类定义的函数(静态联翩)
    2,如果以一个衍生类指针指向一个基础类对象,必须先做强制转型动作(explicit cast),这种做法很危险,也不符合生活习惯,在程序设计上也会给程序员带来困扰。(一般不会这么去定义)
    3,如果基础类和衍生类定义了相同名称的成员函数,那么通过对象指针调用成员函数时,到底调用那个函数要根据指针的原型来确定,而不是根据指针实际指向的对象类型确定。

  • 相关阅读:
    Linux安装nginx
    linux目录结构
    Django-admin
    celery
    Flask-Migrate
    Flask-Script
    Flask-SQLAlchemy
    SQLAlchemy
    mongodb的增删改查
    websocket的加密和解密过程
  • 原文地址:https://www.cnblogs.com/RainyBear/p/5243253.html
Copyright © 2011-2022 走看看