在看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