单例模式
何为单例模式,在GOF的《设计模式:可复用面向对象软件的基础》中是这样说的:保证一个类只有一个实例,并提供一个访问它的全局访问点。首先,需要保证一个类只有一个实例;在类中,要构造一个实例,就必须调用类的构造函数,如此,为了防止在外部调用类的构造函数而构造实例,需要将构造函数的访问权限标记为protected或private;最后,需要提供要给全局访问点,就需要在类中定义一个static函数,返回在类内部唯一构造的实例。意思很明白,使用UML类图表示如下。
1.懒汉式
只有调用GetInstance的时候才会创建单例,但是在多线程环境下有可能会实现多个单例对象
#include <iostream>
#include <string>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class Singleton
{
private:
Singleton() {
m_Test = 10;
}
static Singleton *m_Instance;
int m_Test;
public:
static Singleton *GetInstance(){
if (m_Instance == NULL) {
m_Instance = new Singleton();
}
return m_Instance;
}
static Singleton *DestoryInstance()
{
if (m_Instance != NULL) {
m_Instance = NULL;
}
return m_Instance;
}
int GetTest() {
return m_Test;
}
};
Singleton *Singleton::m_Instance = NULL;
int main() {
Singleton *singletonObj = Singleton::GetInstance();
cout << singletonObj->GetTest() << endl;
Singleton::DestoryInstance();
system("pause");
return 0;
}
2.懒汉式线程安全版
使用了互斥锁和双检锁机制,进行了两次m_Instance == NULL的判断,保证了单例的安全实例化
如果进行大数据操作,互斥锁有可能会成为性能的瓶颈
#include <iostream>
#include <string>
#include <vector>
#include <string>
#include <algorithm>
#include <mutex>
using namespace std;
std::mutex mu;
class Singleton
{
private:
Singleton() {
m_Test = 10;
}
static Singleton *m_Instance;
int m_Test;
public:
static Singleton *GetInstance(){
//双检锁机制
if (m_Instance == NULL) {
//这个机制是为了防止在判断实例是否为空到上锁的间隙 被其他线程实例化
mu.lock();//上锁
if (m_Instance == NULL) {
m_Instance = new Singleton();
}
mu.unlock();//解锁
}
return m_Instance;
}
static Singleton *DestoryInstance()
{
if (m_Instance != NULL) {
m_Instance = NULL;
}
return m_Instance;
}
int GetTest() {
return m_Test;
}
};
Singleton *Singleton::m_Instance = NULL;
int main() {
Singleton *singletonObj = Singleton::GetInstance();
cout << singletonObj->GetTest() << endl;
Singleton::DestoryInstance();
system("pause");
return 0;
}
3.饿汉式
因为静态初始化在程序开始时,也就是进入主函数之前,由主线程以单线程方式完成了初始化,所以静态初始化实例保证了线程安全性。在性能要求比较高时,就可以使用这种方式,从而避免频繁的加锁和解锁造成的资源浪费。
#include <iostream>
#include <string>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
#include <iostream>
using namespace std;
class Singleton
{
private:
Singleton() { m_Test = 10; }
static const Singleton *m_Instance;
int m_Test;
public:
static Singleton *GetInstance()
{
return const_cast <Singleton *>(m_Instance);
}
static void DestoryInstance()
{
if (m_Instance != NULL)
{
delete m_Instance;
m_Instance = NULL;
}
}
int GetTest()
{
return m_Test;
}
};
const Singleton *Singleton::m_Instance = new Singleton();
int main() {
Singleton *singletonObj = Singleton::GetInstance();
cout << singletonObj->GetTest() << endl;
Singleton::DestoryInstance();
system("pause");
return 0;
}
参考文章: