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

发布时间 2023-07-18 10:35:37作者: 一杯清酒邀明月

单例模式

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

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

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

rule.h

 1 #ifndef RULE_H
 2 #define RULE_H
 3 
 4 class Rule
 5 {
 6 public:
 7     static Rule* instance();
 8 };
 9 
10 #endif // RULE_H

rule.cpp

1 #include "rule.h"
2 
3 Q_GLOBAL_STATIC(Rule, rule)
4 
5 Rule* Rule::instance()
6 {
7     return rule();
8 }

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

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

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


抽象工厂模式

主要是利用 Q_INVOKABLE 和 QMetaObject::newInstance

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

 1 class Card : public QObject
 2 {
 3    Q_OBJECT
 4 public:
 5    explicit Card();
 6 };
 7 class CentaurWarrunner : public Card
 8 {
 9    Q_OBJECT
10 public:
11    Q_INVOKABLE CentaurWarrunner();
12 };
13 class KeeperoftheLight : public Card
14 {
15    Q_OBJECT
16 public:
17    Q_INVOKABLE KeeperoftheLight();
18 };

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

 1 #ifndef ENGINE_H
 2 #define ENGINE_H
 3 
 4 #include <QHash>
 5 #include <QList>
 6 #include <QMetaObject>
 7 
 8 class Card;
 9 
10 class Engine
11 {
12 public:
13     static Engine* instance();
14     void loadAllCards();
15     Card* cloneCard(int ISDN);
16 
17 private:
18     QHash<int, const QMetaObject*> metaobjects;
19     QList<Card*> allcards;
20 };
21 
22 #endif // ENGINE_H
 1 #include "engine.h"
 2 #include "card.h"
 3 
 4 Q_GLOBAL_STATIC(Engine, engine)
 5 
 6 Engine* Engine::instance()
 7 {
 8    return engine();
 9 }
10 
11 void Engine::loadAllCards()
12 {
13    allcards << new CentaurWarrunner()
14             << new KeeperoftheLight();
15    for (Card* card : allcards)
16    {
17        metaobjects.insert(card->getISDN(), card->metaObject());
18    }
19 }
20 
21 Card* Engine::cloneCard(int ISDN)
22 {
23    const QMetaObject* meta = metaobjects.value(ISDN);
24    if(meta == nullptr)
25    {
26        return nullptr;
27    }
28    return qobject_cast<Card*>(meta->newInstance());
29 }

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

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