Qt 之实现单例类 Q_GLOBAL_STATIC

单例模式

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

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

你可能感兴趣的:(《Qt,项目实战经历全记录》,qt,单例模式,设计模式)