khala-Study

17 篇文章 0 订阅

目录

MAP

码一码


最近,看了下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;
}

如上,子类通过显示调用父类,即可拥有父类的所有已注册函数,完美。

主要,这样的代码结构设计层次性和拓展型很强,值得借鉴。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值