设计模式-单例模式

单例模式

应用场景

​ 用来创建唯一的实例对象并保证对象唯一

单例模式实现要点

  • 构造函数私有化 - 为避免其他程序过多建立该类对象,先禁止其他程序建立该类对象

  • 类中创建一个本类对象 - 本类中自定义对象,让其他程序可以访问

  • 提供方法获取到该对象 - 方便其他程序对自定义对象的访问

实现方式

懒汉式(线程不安全)

懒汉式(多线程不安全)。需要时候才进行实例化

cpp 复制代码
#include <iostream>
 

class Singleton{
    private:
        Singleton(){}
        Singleton(Singleton&) = delete;
        Singleton& operator=(const Singleton&) = delete;
    public:
        ~Singleton(){}
        static Singleton* getInstance(){
            if(m_instance_ptr == nullptr){
                m_instance_ptr = new Singleton();
            }
            return m_instance_ptr;
        }     
        void use() const { std::cout << "in use" << std::endl; } 
    private:
        static Singleton* m_instance_ptr ;
};


Singleton* Singleton::m_instance_ptr = nullptr;

int main() {
	Singleton* instance = Singleton::getInstance();
	instance->use();

	system("pause");
	return 0;
}
  1. 线程安全的问题:第一个线程在if中判断 m_instance_ptr是空的,于是开始实例化单例;同时第2个线程也尝试获取单例,这个时候判断m_instance_ptr还是空的,于是也开始实例化单例;这样就会实例化出两个对象,这就是线程安全问题的由来; 可以使用加锁解决
  2. 可能存在内存泄漏m_instance_ptr,并不会被释放,除非显示调用

懒汉式(线程安全)

线程安全 + 自动内存释放(使用shared_ptr)

cpp 复制代码
#include <iostream>
#include <memory> // shared_ptr
#include <mutex>  // mutex

class Singleton {
public:
	typedef std::shared_ptr<Singleton> Ptr;
	~Singleton() {
		std::cout << "Singleton - destructor." << std::endl;
	}

	Singleton(Singleton&) = delete; //禁止使用
	Singleton& operator=(const Singleton&) = delete;  //禁止使用

	static Ptr getInstance() {

		if (m_instance_ptr == nullptr) {
			std::lock_guard<std::mutex> auto_lock(m_mutex);
			if (m_instance_ptr == nullptr) {
				 
                m_instance_ptr = std::make_shared<Singleton>();
                /*错误处理:使用new创建std::shared_ptr时,如果构造函数抛出异常,
                那么智能指针将无法正确地释放内存。使用std::make_shared时,如果构造函数抛出异常,
                std::make_shared将自动释放已经分配的内存。*/
			}
		}
		return m_instance_ptr;
	}

	void use() const { 
		std::cout << "Singleton - in use." << std::endl; 
	}


private:
	Singleton() {}
	static Ptr m_instance_ptr;
	static std::mutex m_mutex;
};
Singleton::Ptr Singleton::m_instance_ptr = nullptr;
std::mutex Singleton::m_mutex;

int main() {
	Singleton::Ptr instance = Singleton::getInstance();
	instance->use();

	system("pause");
	return 0;
}

getInstance函数返回一个std::shared_ptr<Singleton>类型的智能指针。当智能指针被销毁时,Singleton对象也会被自动销毁,这样可以确保只有一个Singleton对象被创建,并且对象的生命周期得到自动管理。

饿汉式

  • ,在单例定义的时候进行实例化

    cpp 复制代码
    #include <iostream>
    
    class Singleton {
    public:
    
    	~Singleton() {
    		std::cout << "Singleton - destructor." << std::endl;
    	}
    
    	Singleton(Singleton&) = delete; //禁止使用
    	Singleton& operator=(const Singleton&) = delete;  //禁止使用
    
    	static Singleton* getInstance() {
    		return m_instance;
    	}
    
    	void use() const { 
    		std::cout << "Singleton - in use." << std::endl; 
    	}
    
    
    private:
    	Singleton() {}
    	static Singleton * m_instance;
    
    };
    
    Singleton* Singleton::m_instance = new Singleton();
    
    
    int main() {
    	Singleton* instance = Singleton::getInstance();
    	instance->use();
    
    	system("pause");
    	return 0;
    }
相关推荐
AI人工智能+电脑小能手5 小时前
大白话说Java设计模式-42-访问者模式(业务实战篇)
java·spring·设计模式·访问者模式·asm·营销规则·数据结构与操作分离
AI人工智能+电脑小能手5 小时前
大白话说Java设计模式-43-访问者模式(源码剖析篇)
java·设计模式·访问者模式·源码分析·elementvisitor·asm classvisitor·spring spel
Michael_lcf21 小时前
Agent设计模式:思考-行动-观察循环的本质与局限
设计模式·agent设计模式·agent设计模式的本质
丰锋ff21 小时前
设计模式学习笔记
笔记·学习·设计模式
米啦啦.1 天前
设计模式/
观察者模式·单例模式·设计模式·工厂模式
QuZhengRong1 天前
【AI】Agent 全栈进阶|Agent 设计模式
人工智能·学习·设计模式·llm·agent
码匠许师傅1 天前
【设计模式精讲】2. 设计原则基石:SOLID 与几条关键原则
java·设计模式·log4j
布莱克6051 天前
单例模式详解:什么是单例模式,它能解决哪些问题?
开发语言·qt·单例模式
AI人工智能+电脑小能手1 天前
大白话说Java设计模式-41-备忘录模式(源码剖析篇)
java·设计模式·备忘录模式·源码分析·serializable·undo log·spring statemachine
拓人间精准客1 天前
ToB 销售获客避坑指南:如何用全维度大数据实现降本增效
大数据·数据结构·单例模式