知识巩固之boost的Signals2感悟

在看boost文档的时候有个Signals/Slot的例子:

#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/signals2.hpp>

class Document
{
public:
    Document() {}
    ~Document(){}
public:
    typedef boost::signals2::signal<void()> signal_t;
public:
    /* Connect a slot to the signal which will be emitted whenever
       text is appended to the document. */
    boost::signals2::connection connect(const signal_t::slot_type &subscriber){
        return m_sig.connect(subscriber);
    }
    void append(const char* s){
        m_text += s;
        m_sig(); // send the signal
    }
    const std::string getText(){
        return m_text;
    }
private:
    signal_t m_sig;
    std::string m_text;
};

class TextView{
public:
    TextView(Document& doc):m_doc(doc){
       m_connect = m_doc.connect(boost::bind(&TextView::refresh, this));
    }
    ~TextView(){
        m_connect.disconnect();
    }
    void refresh(){
        std::cout<<"TextView:"<<m_doc.getText()<<std::endl;
    }
private:
    Document& m_doc;
    boost::signals2::connection m_connect;
};

class Controller
{
public:
    Controller() {}
};

int main(){
    Document doc;
    TextView textView(doc);
    doc.append("Hello world!");
    return 0;
}

1、不禁回想起Qt中的消息处理机制:信号/槽 ,十分相似。

这里简单描述下Qt Quick QML中事件处理机制和C++与QML交互方式:

C++代码中通过Q_OBJECT宏让代码编译进元对象中(Qt编译器会自动生成相关文件),其中Q_PROPERTY定义C++中和QML关联的属性,Q_INVOKABLE定义C++中和QML关联的方法;QML中通过元对象的映射可以直接使用C++中定义的这些属性和方法(调用属性和方法),而signals是通过emit传递给QML的信号(返回参数);因此二者可以相互交互。

2、再想下MFC相关的消息映射

声明:
    //{{AFX_MSG  
    afx_msg void OnTimer(UINT nIDEvent);  
    afx_msg void OnPaint();  
    //}}AFX_MSG  
    DECLARE_MESSAGE_MAP() 
映射:
    BEGIN_MESSAGE_MAP(CTestDialog, CDialog)  
    //{{AFX_MSG_MAP(CTestDialog)  
    ON_WM_TIMER()  
    ON_WM_PAINT()  
    ON_MESSAGE(WM_RBUTTONDOWN, OnRButtonDown) // 手动绑定消息
    //}}AFX_MSG_MAP  
    END_MESSAGE_MAP()   
实现:
    void CTestDialog::OnPaint()   
    {  
    }  
      
    void CTestDialog::OnTimer(UINT nIDEvent)   
    {     
        CDialog::OnTimer(nIDEvent);  
    }  
消息映射声明代码:
    #define DECLARE_MESSAGE_MAP() /  
    protected: /  
    static const AFX_MSGMAP* PASCAL GetThisMessageMap(); / // 获得当前类和基类的映射信息  
    virtual const AFX_MSGMAP* GetMessageMap() const; /     // 实际上调用了上一个函数  


消息映射实现代码:
    #define BEGIN_MESSAGE_MAP(theClass, baseClass) /              // 消息映射开始  
    PTM_WARNING_DISABLE /                                    // pragma宏的处理,无关系  
    const AFX_MSGMAP* theClass::GetMessageMap() const /      // 获得自身和基类的函数映射表   
         { return GetThisMessageMap(); } /                        // 入口地址  
    const AFX_MSGMAP* PASCAL theClass::GetThisMessageMap() / // 获得自身函数映射表入口地址  
         { /  
            typedef theClass ThisClass; /                         // 当前类  
        typedef baseClass TheBaseClass; /                     // 基类  
     static const AFX_MSGMAP_ENTRY _messageEntries[] =  /  // 当前类信息实体数组,记录了  
        {                                                     // 该类所有的消息实体  
            // 该行之所以空出来,是因为所有的消息都要写在这里  #define END_MESSAGE_MAP() /                                   // 映射消息的结束,也是消息实  
            {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } /      // 体的最后一个元素,标志结束  
        }; /  
        static const AFX_MSGMAP messageMap = /                // 消息映射变量(包含基类)  
        { &TheBaseClass::GetThisMessageMap, &_messageEntries[0] }; /  
           return &messageMap; /                                  // 返回消息变量   
         }/  
         PTM_WARNING_RESTORE                                  // pragma宏的处理,无关系   

其中消息映射实体数组AFX_MSGMAP_ENTRY _messageEntries[] ——记录了当前类的所有消息映射,就相当于元对象boost中保存Signals/Slot的关系表,当然Qt中也是会有。

很长一段时间没有接触MFC了,消息机制原理参考 https://blog.csdn.net/linzhengqun/article/details/1905671

3.回顾Android 中的消息机制有点不一样,不过和我之前开发kanzi软件时的消息机制大同小异。把消息发送到消息队列中处理,如果是UI相关的放到主线程处理。具体可以参考 https://www.cnblogs.com/all88/p/5430469.html

猜你喜欢

转载自blog.csdn.net/xuqiang918/article/details/81081249