一个类只能创建一个对象,这就是单例模式。该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。
单例模式有两种实现模式:
饿汉模式
程序启动时就创建一个唯一的实例对象
1.创建一个唯一的对象,构造函数首先要是私有的,只允许创建唯一的对象时调用
2.定义一个私有的静态成员变量,在类内由定义的静态成员函数调用
3.为防止通过拷贝构造函数、赋值运算符重载创建对象,它们也要声明成私有的或在C++11中直接delete(删除拷贝构造函数、赋值运算符重载)
优点:1.实现起来简单2.多线程安全
缺点:1.可能会导致进程启动慢2.如果有多个单例类对象实例启动,不确定顺序
class Singleton
{
public:
static Singleton& GetInstance()//获取对象的别名,不会拷贝构造
{
return m_I;
}
private:
Singleton()
{}
//C++11
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
static Singleton m_I;//静态成员变量 静态变量在程序启动时创建好
};
Singleton Singleton::m_I;//在类外初始化
int main()
{
Singleton& s= Singleton::GetInstance();
return 0;
}
懒汉模式
不是在程序启动时创建对象,而是在第一次使用时创建对象
优点:不影响程序启动时的速度,起到延迟加载的作用
缺点:复杂
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<mutex>
#include<thread>
using namespace std;
//懒汉模式
class Singleton
{
public:
static volatile Singleton* GetInstance()
{
//防止线程阻塞
if (m_In == nullptr)
{
m_mutex.lock();//加锁
//检测单个的实例有无创建
if (m_In == nullptr)
m_In = new Singleton;
m_mutex.unlock();//解锁
}
return m_In;
}
//直接写析构,不会直接调用析构函数,为保证调用析构函数,就要定义一个内部类
class CG
{
public:
~CG()
{
if (m_In)
{
delete m_In;
m_In = nullptr;
}
}
};
private:
Singleton()//构造函数
{}
//防拷贝
Singleton(const Singleton&) = delete;//拷贝构造
Singleton& operator=(const Singleton&) = delete;//赋值运算符重载
//
static volatile Singleton* m_In;//静态对象在程序启动时就创建好了,在程序退出的时候销毁
static mutex m_mutex;
static CG m_gc;
};
volatile Singleton* Singleton::m_In = nullptr;
mutex Singleton::m_mutex;
Singleton::CG m_gc;
void ThreadFunc()
{
cout << Singleton::GetInstance() << endl;
}
void Test()
{
thread t1(ThreadFunc);
thread t2(ThreadFunc);
thread t3(ThreadFunc);
thread t4(ThreadFunc);
t1.join();
t2.join();
t3.join();
t4.join();
}
int main()
{
Test();
system("pause");
return 0;
}