松垮垮 松垮垮
首页
  • GPU并行编程
  • 图形学
  • 归并算法
  • 计算机视觉
  • css
  • html
  • JavaScript
  • vue
  • 压缩命令
  • cmdline
  • Docker
  • ftrace跟踪技术
  • gcov代码覆盖率测试
  • GDB
  • git
  • kgdb
  • linux操作
  • markdown
  • systemtap
  • valgrind
  • 设计模式
  • 分布式
  • 操作系统
  • 数据库
  • 服务器
  • 网络
  • C++
  • c语言
  • go
  • JSON
  • Makefile
  • matlab
  • OpenGL
  • python
  • shell
  • 正则表达式
  • 汇编
  • GPU并行编程
  • mysql
  • nginx
  • redis
  • 网络
  • 计算机视觉
  • 进程管理
  • linux调试
  • 【Python】:re.error bad escape i at position 4
  • 搭建ai知识助手
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

松垮垮

c++后端开发工程师
首页
  • GPU并行编程
  • 图形学
  • 归并算法
  • 计算机视觉
  • css
  • html
  • JavaScript
  • vue
  • 压缩命令
  • cmdline
  • Docker
  • ftrace跟踪技术
  • gcov代码覆盖率测试
  • GDB
  • git
  • kgdb
  • linux操作
  • markdown
  • systemtap
  • valgrind
  • 设计模式
  • 分布式
  • 操作系统
  • 数据库
  • 服务器
  • 网络
  • C++
  • c语言
  • go
  • JSON
  • Makefile
  • matlab
  • OpenGL
  • python
  • shell
  • 正则表达式
  • 汇编
  • GPU并行编程
  • mysql
  • nginx
  • redis
  • 网络
  • 计算机视觉
  • 进程管理
  • linux调试
  • 【Python】:re.error bad escape i at position 4
  • 搭建ai知识助手
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 压缩命令
  • cmdline
  • Docker
  • ftrace跟踪技术
  • gcov代码覆盖率测试
  • GDB
  • git
  • kgdb
  • linux操作
  • markdown
  • systemtap
  • valgrind
  • 设计模式

    • Adapter(适配器模式、包装模式)
    • Bridge桥接模式
    • Builder建造者模式
    • Chain
    • Command命令模式
    • Composite组合模式
    • Decorator装饰者
    • Façade门面模式(外观模式)
    • Flyweight享元模式
    • Interpreter解释器模式
    • Iterator迭代器
    • Mediator中介者模式(仲裁者模式)
    • Memento备忘录模式
    • Observer观察者模式
    • Prototype原型
    • Proxy代理模式
    • Singleton单例模式
      • 智能指针+锁
      • 嵌套类+锁
      • ⭐局部对象
    • State状态模式
    • Strategy战略
    • Template
    • Visitor访问者模式
    • •Abstract
    • •Factory
    • 依赖注入(控制反转IoC)
    • 概论
    • 设计模式
  • 工具和开发
  • 设计模式
songkuakua
2025-02-15
目录

Singleton单例模式

# Singleton单例模式

Owner: -QVQ-

创建型

通过单例模式的设计,使得创建的类在当前进程中只有一个实例,并提供一个全局性的访问点,这样可以规避因频繁创建对象而导致的内存飙升情况。

三个要点:

1)私有化构造函数:这样外界就无法自由地创建类对象,进而阻止了多个实例的产生。

2)类定义中含有该类的唯一静态私有对象:静态变量存放在全局存储区,且是唯一的,供所有对象使用。

3)用公有的静态函数来获取该实例:提供了访问接口。

1)懒汉式:在使用类对象(单例实例)时才会去创建它,不然就懒得去搞。

2)饿汉式:单例实例在类装载时构建,有可能全局都没使用过,但它占用了空间,就像等着发救济粮的饿汉提前排好队等吃的一样。

实现单例模式通常面临两个问题,线程安全和内存泄漏。针对线程安全,可通过双重检测锁的方式来解决;针对内存泄漏,可通过资源管理的方式来解决,如智能指针和静态嵌套类

# 一、线程安全的懒汉式实现:

# 智能指针+锁

  1. 用锁实现需要时创建空间
  2. 用智能指针实现程序结束时释放空间
#include <iostream>
#include <mutex>
 
using namespace std;
class Singleton
{
public:
    // 公有接口获取唯一实例
    static shared_ptr<Singleton> getInstance() {
        lock_guard<mutex> l(m_mutex);
        if (instance == nullptr) {// 若为空则创建
            instance.reset(new Singleton(), [](Singleton* x) {
                delete x;
                });
        }
        return instance;
    }
private:
    // 静态私有对象
    static shared_ptr<Singleton> instance;
    static mutex m_mutex;
};

// 初始化
shared_ptr<Singleton> Singleton::instance;
mutex Singleton::m_mutex;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 嵌套类+锁

在类中定义一个删除类,再定义一个这个删除类的静态实例,当所有的类都释放了,会释放这个静态实例,从而调用删除类的析构函数释放空间

写这么麻烦,不如智能指针

// 单例模式演示类
class Singleton
{
public:
	static Singleton* getInstance() {
		if (instance == nullptr) {
			lock_guard<mutex> l(m_mutex);
			if (instance == nullptr) {
				instance = new Singleton();
			}
		}
		return instance;
	}
private:
	// 定义一个删除器
	class Deleter {
	public:
		Deleter() {};
		~Deleter() {
			if (instance != nullptr) {
				delete instance;
				instance = nullptr;
			}
		}
	};
	// 删除器是嵌套类,当该静态对象销毁的时候,也会将单例实例销毁
	static Deleter m_deleter;
private:
	static Singleton* instance;
	static mutex m_mutex;
};
 
// 初始化
Singleton* Singleton::instance = nullptr;
mutex Singleton::m_mutex;
Singleton::Deleter Singleton::m_deleter;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

# ⭐局部对象

局部静态对象在多线程场景下的初始化行为,只有在首次访问时才会创建实例,后续不再创建而是获取

class Singleton
{
public:
	// 公有接口获取唯一实例
	static Singleton* getInstance() {
		static Singleton instance;
		return &instance;
	}
};
1
2
3
4
5
6
7
8
9

# 线程安全的饿汉式实现

在一开始就分配好了空间,后续直接返回这个空间的地址就好

// 单例模式演示类
class Singleton
{
public:
	// 公有接口获取唯一实例
	static Singleton* getInstance() {
		return instance;
	}

private:
	// 静态私有对象
	static Singleton* instance;
};
 
// 初始化
Singleton* Singleton::instance = new Singleton();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

但有内存泄漏问题,解决方法:

  • 智能指针
  • 静态嵌套类
上次更新: 2025/02/21, 14:57:10
Proxy代理模式
State状态模式

← Proxy代理模式 State状态模式→

最近更新
01
搭建ai知识助手
02-23
02
边缘检测
02-15
03
css
02-15
更多文章>
Theme by Vdoing | Copyright © 2025-2025 松垮垮 | MIT License | 蜀ICP备2025120453号 | 川公网安备51011202000997号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 纯净模式