目录
瓢
最近,看了下khala部分源码,对于c++的特性觉得甚是神奇,再次记录一笔,大致画了个瓢。
MAP
如上,大致关系。
- 基本原理:每个对象拥有一个map维护自身函数。
码一码
typedef std::function<bool(int &, QString &, int)> RegisterMessageCallBack;
// 红黑树
typedef QMap<QString, RegisterMessageCallBack> MsgHandleMap;
// 哈希表,查找更高效
//typedef std::unordered_map<QString, RegisterMessageCallBack> MsgHandleMap;
// map
class RegisterHandler{
public:
RegisterHandler(MsgHandleMap &msgHandlerMap);
bool setRegisterMsg(QString &type, RegisterMessageCallBack const &cb);
private:
// Care
MsgHandleMap &m_msgHandleMap;
};
// deltail
class GObject
{
public:
GObject();
virtual ~GObject();
virtual void setRegisterMsg(RegisterHandler &handler) = 0;
// 多态注册
void setRegisterMap();
MsgHandleMap getRegisterMap();
private:
MsgHandleMap m_msgHandleMap;
};
RegisterHandler::RegisterHandler(MsgHandleMap &msgHandlerMap)
:m_msgHandleMap(msgHandlerMap)
{}
bool RegisterHandler::setRegisterMsg(QString &type, const RegisterMessageCallBack &cb)
{
m_msgHandleMap[type] = cb;
return true;
}
GObject::GObject()
{}
GObject::~GObject()
{}
void GObject::setRegisterMap()
{
RegisterHandler handler(m_msgHandleMap);
setRegisterMsg(handler);
}
MsgHandleMap GObject::getRegisterMap()
{
return m_msgHandleMap;
}
如上,这个map存于抽象类,并有handler维护这个map,node:handlder中这个map的引用
class ObjManager
{
public:
ObjManager();
void addObjMap(QString const &type, GObject *obj);
void findAndUse(QVariantMap const &map);
private:
typedef QMap<QString, GObject *> ObjectMap;
ObjectMap m_objMap;
};
void ObjManager::addObjMap(const QString &type, GObject *obj)
{
m_objMap[type] = obj;
// 新增对象方法的注册
obj->setRegisterMap();
}
void ObjManager::findAndUse(QVariantMap const &map)
{
auto it = m_objMap.find(map[OBJECT_TYPE].toString());
if(it != m_objMap.end()){
// why can turn TempObj
if(auto obj = static_cast<GObject *>(it.value())){
MsgHandleMap funMap = obj->getRegisterMap();
qDebug() << "have fun num:: " << funMap.count();
int arg = 10;
QString str = "hello";
for(QMap<QString, RegisterMessageCallBack>::iterator it = funMap.begin(); it != funMap.end(); it++){
it.value()(arg, str, 100);
}
}
}
}
如上,这个管理者其实对管理一个map,维护对象。
// 继承 Gobj
void CusObject::setRegisterMsg(RegisterHandler &handler)
{
// 注册自己新增事件
handler.setRegisterMsg(MSG_CREATE, std::bind(&CusObject::onCreateMsg, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
handler.setRegisterMsg(MSG_DESTORY, std::bind(&CusObject::onDestoryMsg, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
}
bool CusObject::onCreateMsg(int &n, QString &s, int nex)
{
USE_HELP_FUN
return true;
}
bool CusObject::onDestoryMsg(int &n, QString &s, int nex)
{
USE_HELP_FUN
return true;
}
// 继承 CusObj
void SpeObject::setRegisterMsg(RegisterHandler &handler)
{
// 显示调用父类注册,则继承者拥有父类的原来注册的事件
CusObject::setRegisterMsg(handler);
handler.setRegisterMsg(MSG_SPETEST, std::bind(&SpeObject::onSpeTestMsg, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
}
bool SpeObject::onSpeTestMsg(int &n, QString &s, int nex)
{
USE_HELP_FUN
return true;
}
如上,子类通过显示调用父类,即可拥有父类的所有已注册函数,完美。
主要,这样的代码结构设计层次性和拓展型很强,值得借鉴。