c++单例设计模式

博客主要介绍了C++中设计模式里的单例模式,包含懒汉模式和饿汉模式。懒汉模式在需要对象时创建,线程不安全,也有线程安全的加锁及C++11 call_once实现方式;饿汉模式则一开始就创建对象,通过静态函数创建类对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 <iostream>
#include <memory>
#include <mutex>

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值