单例模式的析构学习

1、例子

如果单例对象是类的static成员,那么在程序结束时不会调用类的析构函数,如下:

cpp 复制代码
#include <iostream>
using namespace std;
 
class A{
private:
    static A* m_ins;//声明,静态指针成员
    A(){}
public:
    static A* getIns(){
        if(m_ins==NULL){
            m_ins=new A();
        }
        return m_ins;
    }
    void test(){
      cout<<"testA\n";
    }
    ~A(){
        cout<<"~A destruction\n";
    }
};

A* A::m_ins=nullptr;//定义
int main()
{
    A* a=A::getIns();
    a->test();
    return 0;
}

输出:

cpp 复制代码
testA

需要在返回前单独添加delete A; 否则是会有内存泄漏的风险的,不过上述的例子,程序结束后,操作系统会回收。

使用new创建对象,需要开发人员手动管理。如果不执行delete,对象和分配的内存将一直存在,直到程序退出后,才由操作系统回收。

将静态指针成员改为函数内的静态变量:

cpp 复制代码
class A{
private:
    A(){}
public:
    static A& getIns(){//返回引用
        static A m_a; //  C++11 引入的线程安全的静态变量初始化
        return m_a;
    }
    static A* getIns(){
      static A m_a;
       return & m_a;
    }
};

int main()
{
    A::getIns().test();
    return 0;
}

#输出:
-> % ./Demo
testA
~A destruction

如果使用如下:

cpp 复制代码
    static A* getIns(){
        static A* m_a;
        if(m_a==nullptr){
            m_a = new A();
        }
        return m_a;
    }
main:
A::getIns()->test();

析构函数依旧不会被执行。

2.方法

还可以在内部定义GC类,GC类的析构函数专门用来delete变量。参考:单例模式的析构问题和线程安全问题 | 烫

或者根据 GCC 的 __attribute__((destructor)) 特性,在程序退出阶段(main 函数结束或 exit() 被调用时)会自动调用 _delete()_delete() 负责释放单例实例的内存。

  • 如果没有特殊需求,建议使用静态局部变量实现单例(方式 1)。这种方法最简单,并且是现代 C++ 中的推荐实践。
  • 如果需要明确控制析构时间,推荐使用 atexit() 注册析构函数(方式 4)
相关推荐
凉、介4 小时前
Armv8-A virtualization 笔记 (二)
笔记·学习·嵌入式·arm·gic
z200509304 小时前
每日简单算法题——————跟着卡尔
算法
JoneBB5 小时前
ABAP Webservice连接
运维·开发语言·数据库·学习
️是785 小时前
信息奥赛一本通—编程启蒙(3395:练68.3 车牌问题)
数据结构·c++·算法
嵌入式小企鹅5 小时前
UiPath推出AI编程“总指挥台”,SiFive发布RISC-V第三代猛兽
人工智能·学习·google·程序员·ai编程·risc-v·开源工具
Liangwei Lin6 小时前
LeetCode 118. 杨辉三角
算法·leetcode·职场和发展
计算机安禾6 小时前
【c++面向对象编程】第24篇:类型转换运算符:自定义隐式转换与explicit
java·c++·算法
鼠鼠我(‘-ωก̀ )好困6 小时前
leetGPU
算法
Ada大侦探6 小时前
新手小白学习数据分析03----Excel 报表之大厂周报(2026最新版实操,包教包会!)
学习·数据分析·excel
我星期八休息6 小时前
Linux系统编程—基础IO
linux·运维·服务器·c语言·c++·人工智能·算法