zoukankan      html  css  js  c++  java
  • 单例模式:Qt本身就提供了专门的宏 Q_GLOBAL_STATIC 通过这个宏不但定义简单,还可以获得线程安全性

    标题起的是有点大

    主要是工作和学习中,遇到些朋友,怎么说呢,代码不够Qt化

    可能是由于他们一开始接触的是 Java MFC 吧

    接触 Qt 7个年头了

    希望我的系列文章能抛砖引玉吧


    单例模式

    很多人洋洋洒洒写了一大堆

    比如这里 

    比如这里 

    但是Qt本身就提供了专门的宏 Q_GLOBAL_STATIC

    通过这个宏不但定义简单,还可以获得线程安全性。

    rule.h

    #ifndef RULE_H
    #define RULE_H
    
    class Rule
    {
    public:
        static Rule* instance();
    };
    
    #endif // RULE_H
    

    rule.cpp

    #include "rule.h"
    
    Q_GLOBAL_STATIC(Rule, rule)
    
    Rule* Rule::instance()
    {
        return rule();
    }
    

     

    写法很简单,用法也很简单

    在任何地方,引用头文件 include "rule.h"

    就可以 Rule::instance()->xxxxxx()


    抽象工厂模式

    主要是利用 Q_INVOKABLE 和 QMetaObject::newInstance

    比如说你有一个Card类 card.h 和 2个派生的类

    class Card : public QObject
    {
       Q_OBJECT
    public:
       explicit Card();
    };
    class CentaurWarrunner : public Card
    {
       Q_OBJECT
    public:
       Q_INVOKABLE CentaurWarrunner();
    };
    class KeeperoftheLight : public Card
    {
       Q_OBJECT
    public:
       Q_INVOKABLE KeeperoftheLight();
    };
    

    然后你写一个 engine.h 和 engine.cpp

    #ifndef ENGINE_H
    #define ENGINE_H
    
    #include <QHash>
    #include <QList>
    #include <QMetaObject>
    
    class Card;
    
    class Engine
    {
    public:
        static Engine* instance();
        void loadAllCards();
        Card* cloneCard(int ISDN);
    
    private:
        QHash<int, const QMetaObject*> metaobjects;
        QList<Card*> allcards;
    };
    
    #endif // ENGINE_H
    

     

    #include "engine.h"
    #include "card.h"
    
    Q_GLOBAL_STATIC(Engine, engine)
    
    Engine* Engine::instance()
    {
       return engine();
    }
    
    void Engine::loadAllCards()
    {
       allcards << new CentaurWarrunner()
                << new KeeperoftheLight();
       for (Card* card : allcards)
       {
           metaobjects.insert(card->getISDN(), card->metaObject());
       }
    }
    
    Card* Engine::cloneCard(int ISDN)
    {
       const QMetaObject* meta = metaobjects.value(ISDN);
       if(meta == nullptr)
       {
           return nullptr;
       }
       return qobject_cast<Card*>(meta->newInstance());
    }
    

    这时,你就可以在其他cpp里通过 Card* card = Engine::instance()->cloneCard(ISDN);

    从不同的int值得到不同的Card类型的对象

    https://zhuanlan.zhihu.com/p/32109735

  • 相关阅读:
    使用 libevent 和 libev 提高网络应用性能
    An existing connection was forcibly closed by the remote host
    各种浏览器的兼容css
    vs输出窗口,显示build的时间
    sass
    网站设置404错误页
    List of content management systems
    css footer not displaying at the bottom of the page
    强制刷新css
    sp_executesql invalid object name
  • 原文地址:https://www.cnblogs.com/findumars/p/10392770.html
Copyright © 2011-2022 走看看