什么是单例模式
模式理解
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
UML结构图:
Singleton 类,定义一个 GetInstance 操作,允许客户访问它的唯一实例。GetInstance 是一个静态方法,主要负责创建自己的唯一实例。
现实世界的例子
一次只能有一个国家的总统。无论何时打电话,都必须将同一位总统付诸行动。这里的总统是单身人士。
简单来说
确保只创建特定类的一个对象。
维基百科说
在软件工程中,单例模式是一种软件设计模式,它将类的实例化限制为一个对象。当需要一个对象来协调整个系统的操作时,这非常有用。
单例模式三要点:
- (1)单例类只能有一个实例
- (2)单例类必须自己创建自己的唯一实例
- 通常将构造函数写成private。
- (3)单例类必须给所有其他对象提供这一实例
- 提供一个访问它的全局访问点,通常定义静态方法getInstance()返回。
懒汉模式:
单例模式处理方式要在第一次被引用时,才会将自己实例化,其返回值直到被第一次访问时才创建和保存。
class Singleton
{
private:
static Singleton *instance;
Singleton()//让其private,这样外部程序不能通过其实例化。Singleton obj;错误
{
}
public:
static Singleton* GetInstance()//类操作,即一个静态成员函数
{
if (instance == NULL)//没有实例化的情况下在去实例
{
instance = new Singleton;
}
return instance;
}
static void DestroyInstance()
{
if (instance != NULL)
{
delete instance;
instance = NULL;
}
}
};
Singleton* Singleton::instance = NULL;//静态成员变量类外初始化
客户端代码:
客户端不再考虑是否需要去实例化的问题了,而把责任给了应该负责的类去处理(生不生孩子是自己的责任,社会和国家只负责使用他们)。
int main()
{
Singleton *s1 = Singleton::GetInstance();//第一次被引用,于是将自己实例化
Singleton *s2 = Singleton::GetInstance();
//Singleton *s2 = s1->GetInstance();
if (s1 == s2)
{
cout << "两个对象是相同的实例" << endl;
}
return 0;
}
考虑到多线程安全。在多线程的程序中,多个线程同时访问 Singleton 类,调用 GetInstance() 方法,会有可能造成创建多个实例的情况。
class Singleton
{
private:
static Singleton *instance;
Singleton()
{
}
public:
static Singleton* GetInstance()//类操作,即一个静态成员函数
{
//双重锁定
if (NULL == instance)
{
lock();//实例未创建的情况下加锁,借用其他类实现
if (NULL == instance)
{
instance = new Singleton;
}
unlock();
}
return instance;
}
static void DestroyInstance()
{
if (instance != NULL)
{
delete instance;
instance = NULL;
}
}
};
Singleton* Singleton::instance = NULL;//静态成员变量类外初始化
从代码我们可以看出,懒汉式单例模式的创建对象是在第一次企图获得单例类的对象时。
饿汉模式:
静态初始化实例方式,在自己被加载时就将自己实例化,提前占用系统资源。
其可以保证线程安全性,因为静态实例初始化在程序开始进入主函数之前就由主线程以单线程方式完成了初始化,不必担心多线程问题。
class Singleton
{
private:
static const Singleton *instance;
Singleton()
{
}
public:
static const Singleton* GetInstance()
{
return instance;
}
static void DestroyInstance()
{
if (instance != NULL)
{
delete instance;
instance = NULL;
}
}
};
//进入主函数之前就完成了实例初始化,是线程安全的
const Singleton* Singleton::instance = new Singleton;
//客户端代码
int main()
{
const Singleton *s1 = Singleton::GetInstance();
const Singleton *s2 = Singleton::GetInstance();
//const Singleton *s2 = s1->GetInstance();
if (s1 == s2)
{
cout << "两个对象是相同的实例" << endl;
}
Singleton::DestroyInstance();
return 0;
}
参考:《大话设计模式》