单例模式的析构学习

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)
相关推荐
白狐_7982 分钟前
408 数据结构|KMP算法核心:为什么不用主串回退
数据结构·算法
我是你的开心果7788 分钟前
ai全栈应用开发学习day19
学习
wuyk5558 分钟前
13.堆排序:基于完全二叉树的高效排序算法一、什么是堆排序?
开发语言·算法·排序算法
qinzechen13 分钟前
本周科技行业热点汇总·2026第36周(2026年8月31日-9月6日)
c++·科技·算法
白狐_79828 分钟前
408 数据结构|红黑树 vs AVL:高频考点、易错判断与可能出题方式
数据结构·算法
zuozong_33 分钟前
C++类与对象
开发语言·c++·算法
是隼人37 分钟前
buuctf-pwn wustctf2020_closed(文件描述符)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
hansang_IR37 分钟前
【代码】分层最短路模板
c++·算法·最短路
励志不掉头发的内向程序员42 分钟前
【LibreCAD 2D架构】从两个坐标到图形实体:RS_ActionDrawLine如何创建RS_Line
开发语言·c++·qt·学习·系统架构
啊阿狸不会拉杆1 小时前
《计算机网络-自顶向下方法》5.2 路由选择算法 读书笔记
计算机网络·算法·路由