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

标题起的是有点大

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

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

接触 Qt 7个年头了

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


单例模式

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

比如这里 http://xtuer.github.io/qtbook-singleton/

比如这里 http://m.blog.csdn.net/Fei_Liu/article/details/69218935

但是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

原文地址:https://www.cnblogs.com/findumars/p/10392770.html

时间: 2024-11-01 22:47:11

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

ConcurrentHashMap和 CopyOnWriteArrayList提供线程安全性和可伸缩性 以及 同步的集合类 Hashtable 和 Vector Collections.synchronizedMap 和 Collections.synchronizedList 区别缺点

ConcurrentHashMap和 CopyOnWriteArrayList提供线程安全性和可伸缩性 DougLea的 util.concurrent 包除了包含许多其他有用的并发构造块之外,还包含了一些主要集合类型 List 和 Map 的高性能的.线程安全的实现.在本月的 Java理论与实践中,BrianGoetz向您展示了用 ConcurrentHashMap 替换 Hashtable 或 synchronizedMap ,将有多少并发程序获益. 在Java类库中出现的第一个关联的集合类

mcrypt本身就提供了强大的加密解密方法

由于项目的需要,要写一个能生成“授权码”的类(授权码主要包含项目使用的到期时间),生成的授权码将会写入到一个文件当中,每当项目运行的时候,会自动读取出文件中的密文,然后使用唯一的“密钥”来调用某个函数,对密文进行解密,从中解读出大都会娱乐城项目的使用到期时间. 之前,自己有先试着写了下,主要是base64+md5+反转字符串.算法太过简单,很容易被破解,而且也没有能过做到“密钥”在加解密中的重要性,故而舍之. 后来,查找了相关资料,发现,原来PHP中内置了一个功能强大的函数库,即Mcrypt.

一天一个设计模式——(Singleton)单例模式(线程安全性)

一.模式说明 有时候,我们希望在应用程序中,仅生成某个类的一个实例,这时候需要用到单例模式. 二.模式类图 三.模式中的角色 Singleton角色,该模式中仅有的一个角色,该角色有一个返回唯一实例的getInstance方法,该方法总是返回同一个实例: 四.代码示例 单例模式比较简单,要实现单例模式只需保证三点: 私有化类的构造函数: 在类中创建类的对象: 提供获取对象的公有方法: package com.designpattern.cn.singletonpattern; public cl

单例模式的写法和线程安全性的讨论

//饿汉模式:单例模式,就是无论用不用,什么时候用,在类加载的时候就实例化一个这个类的对象 //然后等到使用的时候,就是使用同一个实例对象 //好处:在多线程的环境下使用这种方法,可以避免多线程带来的冲突.与之相对应的是,懒汉模式(按需实例化) class Singleton1{ private Singleton1(){} private static Singleton1 s1 = new Singleton1(); public static Singleton1 getSingleton

Java单例模式以及线程安全性的保证

1.单例模式有什么用处? 有一些对象只能使用一个,例如:数据库连接.线程池(threadpool).缓存(cache).对话框.处理偏好(preferences)设置和这侧表(registry)的对象.日志对象.充当打印机.显卡等设备的驱动程序的对象,即用于管理共享的资源.这种对象只能有一个实例,制造多个会导致问题. 2.最经典的单例模式?         /**      * 1.利用一个私有静态变量来记录Singleton类的唯一实例:      * 2.构造器声明为私有,只有Singlet

如何保证单例模式在多线程中的线程安全性

对大数据.分布式.高并发等知识的学习必须要有多线程的基础.这里讨论一下如何在多线程的情况下设计单例模式.在23中设计模式中单例模式是比较常见的,在非多线程的情况下写单例模式,考虑的东西会很少,但是如果将多线程和单例模式结合起来,考虑的事情就变多了,如果使用不当(特别是在生成环境中)就会造成严重的后果.所以如何使单例模式在多线程中是安全的显得尤为重要,下面介绍各个方式的优缺点以及可用性: 1.立即加载(饿汉模式) 立即加载模式就是在调用getInstance()方法前,实例就被创建了,例: pub

单例模式的线程安全性

单例模式是设计模式中比较简单的一种.适合于一个类只有一个实例的情况,比如窗口管理器,打印缓冲池和文件系统, 它们都是原型的例子.典型的情况是,那些对象的类型被遍及一个软件系统的不同对象访问,因此需要一个全局的访问 指针,这便是众所周知的单例模式的应用. 经典的单例模式有三种,懒汉式.饿汉式和懒汉式单例模式改进式 "懒汉式"是在你真正用到的时候才去建这个单例对象,所以是线程不安全的 懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的.   测试懒汉

Qt自己定义事件实现及子线程向主线程传送事件消息

近期在又一次学习Qt的时候,由于要涉及到子线程与主线程传递消息,所以便琢磨了一下.顺便把有用的记录下来,方便自己以后查询及各位同仁的參考! 特此声明,本篇博文主要讲述有用的,也就是直接说明怎么实现,就不打算陈述一大堆理论啦,只是,还是建议大家去查查对应的理论比較好.这样能对Qt的消息传送机制的理解更加深入. 依据网上大多数人的资料,要实现自己定义消息,须要从QEvent 派生一个自己定义的事件:事实上也能够不须要,仅仅要使用QEvent::Type自己定义一个事件即可了. 在这里,本人把两种实现

单例模式中的懒汉式以及线程安全性问题

先看代码: package com.roocon.thread.t5; public class Singleton2 { private Singleton2(){ } private static Singleton2 instance; public static Singleton2 getInstance(){ if(instance == null) {//1:读取instance的值 instance = new Singleton2();//2: 实例化instance } re