作为一种常用的软件设计模式,单例模式保证了类在系统中的唯一性,唯一实例通过接口供外界访问,提供了对实例个数的控制并节约了系统资源。从数学的角度而言,若将系统中的同一类归为一个集合,则单例模式即为最多仅有一个元素的集合。
由于单例模式需要保证类实例的唯一性,因此不能提供公共构造函数对类进行实例化操作。将构造函数私有,通过公共接口GetInstancePtr()提供对实例化类的访问,同时需要考虑到多线程场景下的线程安全性。具体代码实现如下:
#ifndef _SINGLETON_H
#define _SINGLETON_H
class Singleton
{
public:
static Singleton& GetInstance();
static Singleton* GetInstancePtr();
void AutoIncrement();
int GetIndex();
private:
Singleton():index(0){}
virtual ~Singleton();
static Singleton *instancePtr;
int index;
};
#endif
#include "Singleton.h"
#define nullptr 0
Singleton* Singleton::instancePtr = nullptr;
Singleton::~Singleton()
{
if(nullptr != instancePtr)
{
instancePtr = nullptr;
}
}
Singleton& Singleton::GetInstance()
{
return *GetInstancePtr();
}
Singleton* Singleton::GetInstancePtr()
{
static Singleton m_instance;
if(nullptr == instancePtr)
{
instancePtr = &m_instance;
}
return instancePtr;
}
void Singleton::AutoIncrement()
{
index++;
}
int Singleton::GetIndex()
{
return index;
}
以上是采用懒汉模式的的单例模式,当第一次调用这个类的时候将产生这个类的一个实例。与之相对应的还有饿汉模式下的单例,即无论是否调用该类的实例,都将在程序开始运行时产生一个该类的实例,并在以后仅返回该实例。
采用静态初始化的优势在于保障了线程安全性,由于静态实例的初始化发生在主线程进入main()函数之前,同时当主程序退出后将自动进行析构。采用这种方式可以有效避免锁争夺的发生,当对系统性能要求较高时,可采用这种方式。