c++单例设计模式

文章目录

  • 1.单例模式
  • 2.饿汉模式
  • 3.懒汉模式(线程安全,加锁)
  • 4.懒汉模式(c++11线程安全 :call_once)

1.单例模式

单例模式有两种
1.1 懒汉模式(线程不安全)
需要用到对象的时候才开始创建,多个线程调用的时候可能会创建多个对象
1.2 饿汉模式(线程安全)
一开始就创建一个对象

将构造函数私有化,不允许外部构造,声明一个静态的类指针,和静态的getInstance()函数,通过域名调用getInstance()函数来创建类对象

2.饿汉模式

 class Singleton
 {
 public:
	 // 获取单实例
	 static Singleton* GetInstance() 
	 {
		 return g_pSingleton;
	 };

	 // 释放单实例,进程退出时调用
	 static void deleteInstance()
	 {
		 if (g_pSingleton)
		 {
			 delete g_pSingleton;
			 g_pSingleton = nullptr;
		 }
	 };

 private:
	 // 将其构造和析构成为私有的, 禁止外部构造和析构
	 Singleton() {};
	 ~Singleton() {};

	 //禁用拷贝构造和赋值构造
	 Singleton(const Singleton &signal)=delete;
	 const Singleton &operator=(const Singleton &signal)=delete;

 private:
	 // 唯一单实例对象指针
	 static Singleton *g_pSingleton;
 };

 Singleton *Singleton::g_pSingleton = new Singleton;

3.懒汉模式(线程安全,加锁)

 class Singleton
 {
 public:
	 // 获取单实例
	 static Singleton* GetInstance() 
	 {
		 if (g_pSingleton == nullptr)
		 {
			 unique_lock<mutex> lock(m_mtx);
			 if (g_pSingleton == nullptr)
			 {
				 volatile auto temp = new Singleton;
				 g_pSingleton = temp;
				 /*
				 因为在并发场景下可能会出现问题。
				singleton 对象在初始化的时候实际上是分三步的:
				1. 先申请一块内存;
				2. 再调用构造函数进行初始化;
				3. 将内存地址赋值给 singleton 。
				但是上述操作在不同编译器上表现可能是不一样的,可能先将内存地址赋值给 singleton ,
				再调用构造函数进行初始化。那在并发场景下,线程拿到的 singleton 可能是还未构造完成的单例对象,在使用时可能出现问题。
				先赋值给 temp 在赋值给 singleton ,可以保证返回的单例对象一定是初始化完成的。
				 */
			 }
		 }
		 return g_pSingleton;
	 };

	 // 释放单实例,进程退出时调用
	 static void deleteInstance()
	 {
		 unique_lock<mutex> lock(m_mtx);
		 if (g_pSingleton)
		 {
			 delete g_pSingleton;
			 g_pSingleton = nullptr;
		 }
	 };
 private:
	 // 将其构造和析构成为私有的, 禁止外部构造和析构
	 Singleton() {};
	 ~Singleton() {};

	 //禁用拷贝构造和赋值构造
	 Singleton(const Singleton &signal)=delete;
	 const Singleton &operator=(const Singleton &signal)=delete;

 private:
	 // 唯一单实例对象指针
	 static Singleton *g_pSingleton;
	 static mutex m_mtx;
 };
 Singleton *Singleton::g_pSingleton = nullptr;

4.懒汉模式(c++11线程安全 :call_once)

call_once:保证函数只被执行一次。
#include 
#include 
#include 

class Singleton {
public:
    static std::shared_ptr<Singleton> getSingleton();
    ~Singleton() {};
private:
    Singleton() { };
};

static std::shared_ptr<Singleton> singleton = nullptr;
static std::once_flag singletonFlag;

std::shared_ptr<Singleton> Singleton::getSingleton() {
    std::call_once(singletonFlag, [&] {
        singleton = std::shared_ptr<Singleton>(new Singleton());
    });
    return singleton;
}

你可能感兴趣的:(设计模式,c++,设计模式)