单例模式:饿汉模式与懒汉模式

一个类只能创建一个对象,这就是单例模式。该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。
单例模式有两种实现模式:

饿汉模式

程序启动时就创建一个唯一的实例对象

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;
}
发布了73 篇原创文章 · 获赞 2 · 访问量 2852

猜你喜欢

转载自blog.csdn.net/weixin_43219708/article/details/104245747