一、概念
一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全 局访问点,该实例被所有程序模块共享。
二、恶汉模式
不管是否使用,在程序启动时就创建的唯一实例对象
class Singleton
{
public:
static Singleton* GetInstrance()
{
return &m_ps;
}
private:
Singleton(Singleton &s)
{}
private:
static Singleton m_ps;
};
Singleton Singleton::m_ps;
三、懒汉模式
1. 注意
(1)保证只能创建一个对象,将构造函数定义成私有的成员函数
(2)提供一个静态成员的方法:如果对象没有创建,创建对象
(3)防止被拷贝
2. 缺陷
(1)线程不安全 -- 加锁
(2)只要有一个线程获取对象,所有线程都会被阻塞 -- 双阻塞 -- 降低阻塞概率
(3)如果编译器对代码指针进行重排,对象可能船检不完整
(4)什么时机释放单例对象:保证所有线程都不使用 -- 在程序退出时
封住内部类,在内部类析构函数中释放单例,并在单例类中创建内部类的对象
3. 代码
#include <iostream>
#include <string.h>
#include <thread>
#include <mutex>
using namespace std;
class Singleton
{
public:
static Singleton* GetInstrance();
class GC
{
public:
~GC();
};
private:
Singleton();
Singleton(const Singleton&);
Singleton& operator=(Singleton const&);
private:
static Singleton* volatile m_ps;
static mutex m_mutex;
static GC m_gc;
};
Singleton* volatile Singleton::m_ps = nullptr;
mutex Singleton::m_mutex;
Singleton::GC m_gc;
Singleton* Singleton::GetInstrance()
{
if (nullptr == m_ps)
{
m_mutex.lock();
if (nullptr == m_ps)
{
m_ps = new Singleton();
cout << "Create success" << endl;
}
m_mutex.unlock();
}
return m_ps;
}
Singleton::GC::~GC()
{
if (nullptr == m_ps)
{
if (nullptr == m_ps)
{
delete m_ps;
m_ps = nullptr;
}
}
}
Singleton::Singleton()
{}
void func(int a)
{
Singleton::GetInstrance();
}
int main()
{
thread t1(func, 10);
thread t2(func, 10);
t1.join();
t2.join();
cout << Singleton::GetInstrance() << endl;
cout << Singleton::GetInstrance() << endl;
return 0;
}
C++ 11 后的方法
class Singleton
{
public:
static Singleton* getInstance();
static std::atomic<Singleton*> Singleton::m_instance;
static std::mutex Singleton::m_mutex;
private:
Singleton() = delete;
Singleton(const Singleton& other) = delete;
};
std::atomic<Singleton*> Singleton::m_instance;
std::mutex Singleton::m_mutex;
Singleton* Singleton::getInstance()
{
Singleton* temp = m_instance.load(std::memory_order_relaxed);
std::_Atomic_thread_fence(std::memory_order_acquire);
if (temp == nullptr)
{
std::lock_guard<std::mutex> lock(m_mutex);
temp = m_instance.load(std::memory_order_relaxed);
if (temp == nullptr)
{
m_instance = new Singleton;
std::atomic_thread_fence(std::memory_order_release);
m_instance.store(temp, std::memory_order_relaxed);
}
}
return temp;
}