惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Jina AI
Jina AI
博客园 - Franky
Apple Machine Learning Research
Apple Machine Learning Research
酷 壳 – CoolShell
酷 壳 – CoolShell
阮一峰的网络日志
阮一峰的网络日志
量子位
雷峰网
雷峰网
宝玉的分享
宝玉的分享
V
Visual Studio Blog
博客园_首页
小众软件
小众软件
The Cloudflare Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
大猫的无限游戏
大猫的无限游戏
博客园 - 聂微东
S
SegmentFault 最新的问题
博客园 - 【当耐特】
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 叶小钗
月光博客
月光博客
博客园 - 三生石上(FineUI控件)
人人都是产品经理
人人都是产品经理
WordPress大学
WordPress大学

博客园 - 于光远

泛型编程 分区理论知识整理 SPI协议及驱动开发框架 I2C协议及驱动开发框架 使用qemu 加载linux-6.18.1内核 linux 内核 策略模式 Linux性能分析:从监控到优化的完整工具链 C++模板元编程实现序列化与反序列化 引用 bootchart linux 脚本打印时间 接口编程 不定参数解析,结合tuple 独立于main运行的程序 类模板继承 std::ostream & operator<< Flash HIDL --HelloWorld
单例模式
于光远 · 2025-11-10 · via 博客园 - 于光远

单例模式

单例模式,指的是,在一些特定的场景当中,某一些类只能创建出一个实例(对象)。无论是单线程还是多线程环境下面,都只能生成一个对象,这个时候,就需要使用到单例模式。

主要是为了防止一个类实例化多个对象造成数据不一致问题或者造成资源消耗问题(构建过程中的时间消耗、内存消耗)

怎么设置单例模式

  1. 私有化构造函数:确保单例类的构造函数私有的,这样外部就不能通过new关键字直接创建对象。
  2. 静态成员变量:使用静态成员变量来存储唯一实例。
  3. 静态方法:提供一个静态成员函数,用来返回这个唯一实例。这个方法通常是公有的。
  4. 延迟初始化:如果单例对象的创建比较耗时,可以考虑在第一次使用时才进行创建。

饿汉:

在类加载时就立即创建单例对象,并将其存储在静态成员变量中。

优点:类对象的创建特别快速,因为类的加载是一个比较靠前的阶段。 线程安全

缺点:创建后不使用,就会有长时间占用内存资源。

class Singleton {
    //1.构造器私有化,只能在内部new对象
    private Singleton(){
    }
    //2.内部实例化
    private final static Singleton instance =new Singleton();
    //3.提供get方法供外部使用,返回实例对象
    public static Singleton getInstance(){
        return instance;
    }
 
}

懒汉:

单例实例在第一次被使用时才进行初始化

优点:真正需要使用某个类的实例的时候,才会创建,这样不会造成资源的浪费

缺点:使用了锁机制,第一次使用时候,多一次构造时间。

class Singleton 
{ 
private: 
    static Singleton* m_instance; 
    Singleton(){} 
public: 
    static Singleton* getInstance(); 
}; 
   
Singleton* Singleton::getInstance() 
{ 
    if(NULL == m_instance) 
    { 
        Lock();//借用其它类来实现,如boost 
        if(NULL == m_instance) 
        { 
            m_instance = new Singleton; 
        } 
        UnLock(); 
    } 
    return m_instance; 
}

融入模板

#pragma once
#include <mutex>
template <class T>
class Singleton{
  public:
    static T* getInstance() {
     
        if (_singleton == nullptr) {
            std::lock_guard<std::recursive_mutex> lock(_mtx);
            if (_singleton == nullptr)
                _singleton = new T();
        }

        return _singleton;
    }
    static void destroyInstance() {
        std::lock_guard<std::recursive_mutex> lock(_mtx);

        if (_singleton != nullptr)
            delete _singleton;

        _singleton = nullptr;
    }

  private:
    Singleton() {}
    virtual ~Singleton() {}

  private:
    static std::recursive_mutex _mtx;
    static T*                   _singleton;
};

template <class T>
std::recursive_mutex Singleton<T>::_mtx;

template <class T>
T* Singleton<T>::_singleton = nullptr;

#define SINGLETON_CLASS(T) friend class Singleton<T>;

使用方式

class A {
    SINGLETON_CLASS(A)
  public:
    void func(){}
  private:
    A(){}
    ~A(){}
};

int main(){
    Singleton<A>::getInstance->func();
}

posted @ 2025-11-10 09:14  于光远  阅读(19)  评论()    收藏  举报