Qt 之实现单例类 Q_GLOBAL_STATIC

单例模式

确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。
单例模式即确保程序的唯一性,与全局对象不一样的是,单例类往往是在第一次使用的时候才创建。
单例模式有三个要点:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。
结构图如下:
在这里插入图片描述

单例模式应该是程序最常用的类设计模式;分为懒汉式、饿汉式等多种,目的是确保唯一,线程安全。
本文列举了三种来实现单例模式的方法。推荐使用第三种。Q_GLOBAL_STATIC

Q_GLOBAL_STATIC

宏定义介绍
Q_GLOBAL_STATIC(Type, VariableName)
由Q_GLOBAL_STATIC创建的对象在首次使用时进行初始化,它不会增加应用程序或库的加载时间。此外,该对象在所有平台上都以线程安全的方式初始化的。
这个宏的典型用法如下,在全局上下文中(即,在任何函数体之外):

Q_GLOBAL_STATIC(MyType, staticType)

这个宏旨在替代不是POD的全局静态对象(普通的旧数据,或者用C ++ 11的术语,不是由平凡的类型组成),因此也就是名称。例如,下面的C ++代码创建一个全局静态:

static MyType staticType;

与Q_GLOBAL_STATIC相比,假设这MyType是一个具有构造函数,析构函数的类或结构,或者是非POD,上面写法有以下缺点:

  1. 项目1它需要加载时初始化MyType(即MyType加载库或应用程序时调用的默认构造函数);
  2. 即使从未使用过,类型也会被初始化;
  3. 不同的单元之间的初始化和破坏的顺序不确定,导致在初始化之前或销毁之后可能会使用;
  4. 如果它是在一个函数内(即不是全局的)发现的,它将在第一次使用时被初始化,但是许多当前编译器中并不保证初始化是线程安全的;

Q_GLOBAL_STATIC宏通过在第一次使用时保证线程安全初始化并允许用户查询类型是否已被销毁以避免销毁后使用问题来解决上述所有问题。

注意:如果要使用该宏,那么类的构造函数和析构函数必须是公有的才行,如果构造函数和析构函数是私有或者受保护的类型,是不能使用该宏的。

对于具有受保护或私有默认构造函数或析构函数的类型(对于Q_GLOBAL_STATIC_WITH_ARGS(),一个与参数匹配的受保护或私有构造函数),不能使用Q_GLOBAL_STATIC 。如果将这些成员保护起来,可以通过从类型派生出来并创建公共构造函数和析构函数来解决问题。如果类型将它们设为私有,则派生之前需要声明friend。

例如,MyType基于先前定义的MyOtherType具有受保护的默认构造函数和/或受保护的析构函数

class MyType : public MyOtherType { };
  Q_GLOBAL_STATIC(MyType, staticType)

MyType由于析构函数是隐式成员,因此不需要定义,如果没有定义其他构造函数,则默认构造函数也是如此。但是,与Q_GLOBAL_STATIC_WITH_ARGS()一起使用时,需要一个合适的构造函数体:

 class MyType : public MyOtherType
  {
  public:
      MyType(int i) : MyOtherType(i) {}
  };
  Q_GLOBAL_STATIC_WITH_ARGS(MyType, staticType, (42))

方式1:

最基本的方式

class ApiManager : public QObject
{
    Q_OBJECT

public:
    ApiManager();
    static ApiManager* GetInstance();
}
ApiManager *ApiManager::GetInstance()
{
    static ApiManager stInsatance;
    return &stInsatance;
}

方式2:

.h文件
注意构造函数是protect权限

class CommonSingleton :public QObject
{
    Q_OBJECT
public:
    static CommonSingleton *GetInstance();
protected:
    CommonSingleton();
    ~CommonSingleton();
private:
    class CRelease
    {
    public:
        ~CRelease();
    };

    static CommonSingleton *m_pInstance;
    static CRelease release;
};

cpp

CommonSingleton *CommonSingleton::m_pInstance = NULL;
CommonSingleton::CRelease CommonSingleton::release;

CommonSingleton *CommonSingleton::GetInstance()
{
    if(NULL == m_pInstance)
    {
        m_pInstance = new CommonSingleton();
    }
    return m_pInstance;
}
CommonSingleton::CommonSingleton()
{
}
CommonSingleton::~CommonSingleton()
{
}

CommonSingleton::CRelease::~CRelease()
{
    if (CommonSingleton::m_pInstance)
    {
        qDebug() << "*************Singleton destruction***********";
        delete CommonSingleton::m_pInstance;
        CommonSingleton::m_pInstance = NULL;
    }
}

方式3:

.h

class ApiManager : public QObject
{
    Q_OBJECT

public:
    ApiManager();
    static ApiManager* GetInstance();
 }

.cpp

Q_GLOBAL_STATIC(ApiManager, apiManager)
ApiManager::ApiManager()
{

}
ApiManager *ApiManager::GetInstance()
{
    return  apiManager;
}
  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值