单列类 自动释放(懒汉式加载 )

本文详细介绍了单例模式的设计理念,即确保一个类只有一个实例并全局可访问。通过私有构造函数和静态成员函数实现,引入自动释放机制,利用静态类在程序结束时自动释放单例对象,避免内存泄漏。

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

单例模式,可能是使用很广泛的设计模式。其意图是保证一个类仅有一个实例,并且可以被全局使用。
单列类 就是定义一个类,使用私有构造防止其他调用,在使用类的私有静态指针变量指向类的唯一实例,并用一个公有的静态方法获取该指针。
对于 单列类释放问题,手动销毁就显得非常麻烦,并且容易忘记释放。所以实现一个自动释放指针的单列类就显得很重要了。因为我们定义的静态变量是放在全局区上的,受系统控制释放,所以我们程序结束自动释放静态变量这一特点来解决该问题。我们在类中定义一个静态类,这个类专门用来释放单列指针。下面附上代码

class singleRow   //单列类
{

public:
  	  static singleRow* GetSingleRow()  //获取单列指针     
    {
    if(m_psingleRow == nullptr)  //判断是否已经创建该类 
    {
        m_psingleRow = new singleRow();
    }
    return m_psingleRow;
    }
private:
    singleRow(){}  //私有构造

   //垃圾回收类  释放单列指针
    class Garbo
    {
    public:
        ~Garbo()
        {
            if(singleRow::m_psingleRow != nullptr)   
            {
                delete  singleRow::m_psingleRow ;   
                singleRow::m_psingleRow = nullptr;
            }
        }
    };

   static Garbo garbo;   //定义静态变量  系统结束自动释放该类  调用析构方法从而释放指针
   static singleRow* m_psingleRow; //单列类实列静态指针
};
//静态变量初始化
singleRow::Garbo singleRow::garbo; 
singleRow* singleRow::m_psingleRow = nullptr;
<think>好的,我现在需要向用户介绍懒汉(延迟加载)的设计模。首先,我应该回忆一下单例模式的基本概念,因为懒汉是其中的一种实现方单例模式确保一个类只有一个实例,并提供全局访问点。懒汉的特点是在第一次使用时才创建实例,而不是在类加载时就创建,这样可以节省资源。 接下来,我需要确定懒汉的关键点。延迟加载,也就是实例在需要的时候才被创建,这是核心。但要注意线程安全的问题,因为在多线程环境下,可能会创建多个实例。所以需要解释线程安全的重要性以及如何通过同步机制来解决,比如使用synchronized关键字或者双重检查锁定。 然后,我需要考虑如何用代码示例来说明这一点。可能先展示一个基础的懒汉实现,但指出其线程不安全的问题。再逐步改进,加入同步块或双重检查锁定,并解释为什么这样修改可以保证线程安全。同时,提到volatile关键字在双重检查锁定中的作用,防止指令重排序导致的异常。 另外,可能需要对比饿汉,说明懒汉的优缺点。优点包括资源利用高效,缺点则是实现稍复杂,需要考虑线程安全,可能影响性能。但双重检查锁定可以在一定程度上减少同步的开销。 还要注意用户可能对某些术语不太熟悉,比如“延迟加载”、“线程安全”、“双重检查锁定”等,需要用简洁的语言解释清楚。同时,确保代码示例的正确性,避免语法错误,并且符合用户指定的格,比如使用$$...$$包围独立的代码块,行内公用$...$。 最后,检查回答是否结构清晰,分点说明,覆盖定义、特点、线程安全处理、代码示例、优缺点等方面。确保语言口语化,避免过于技术化的表述,让用户容易理解。同时,按照用户要求使用中文,并且正确应用LaTeX格,比如变量用$x$这样的形。</think>懒汉(延迟加载)是**单例模式**的一种实现方,其核心特点是**在首次使用时才创建实例**(而非提前初始化),目的是减少资源占用。以下是关键要点: --- ### 核心特点 1. **延迟加载** 实例在第一次调用`getInstance()`时才被创建,避免类加载时就初始化对象。 ```java public class LazySingleton { private static LazySingleton instance; // 不提前初始化 public static LazySingleton getInstance() { if (instance == null) { // 首次访问时创建 instance = new LazySingleton(); } return instance; } } ``` 2. **线程安全问题** 基础版懒汉**非线程安全**,多线程同时调用`getInstance()`可能导致创建多个实例。 **解决方案**: - **同步方法**(简单但性能较低) ```java public static synchronized LazySingleton getInstance() { if (instance == null) { instance = new LazySingleton(); } return instance; } ``` - **双重检查锁定(DCL)**(更高效) ```java public class LazySingleton { private static volatile LazySingleton instance; // volatile防止指令重排序 public static LazySingleton getInstance() { if (instance == null) { // 第一次检查 synchronized (LazySingleton.class) { // 加锁 if (instance == null) { // 第二次检查 instance = new LazySingleton(); } } } return instance; } } ``` --- ### 对比饿汉 | **特性** | **懒汉** | **饿汉** | |----------------|-------------------------------|-------------------------------| | 初始化时机 | 首次调用时 | 类加载时 | | 资源占用 | 更节省内存 | 可能提前占用未使用的资源 | | 实现复杂度 | 需处理线程安全 | 天然线程安全(类加载机制保证) | | 典型场景 | 实例创建成本高或使用频率低 | 简单场景或实例轻量 | --- ### 适用场景 - 对象创建**成本高**(如连接数据库、读取大文件) - 实例**使用频率低**,避免不必要的初始化 - 需动态控制实例化时机 --- ### 注意事项 - **避免反射破坏单例**:可通过在构造器中抛出异常防止反射调用。 - **序列化问题**:实现`readResolve()`方法确保反序列化时返回同一实例。 - **双重检查锁定中必须使用`volatile`**:防止JVM指令重排序导致返回未初始化的对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值