C++ | 单例设计模式(懒汉式单例模式源码|饿汉式单例模式)

2024-09-08 00:20

本文主要是介绍C++ | 单例设计模式(懒汉式单例模式源码|饿汉式单例模式),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

点击上方"蓝字"关注我们

01、概念

>>>

单例设计模式(Singleton Pattern)是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点来访问该实例。单例模式通常用于需要在整个应用程序中共享一个对象的场景,例如配置管理、日志记录、数据库连接池等。

02、场景

>>>

应用场景

  1. 配置管理:应用程序的配置信息通常只需要一个实例来管理,避免多个配置实例导致数据不一致。

  2. 日志记录:日志记录器通常只需要一个实例,以便所有模块都能记录到同一个日志文件中。

  3. 数据库连接池:数据库连接池只需要一个实例来管理数据库连接,避免资源浪费。

  4. 线程池:线程池只需要一个实例来管理线程的创建和销毁。

03、多线程如何处理到单例模式 ?

>>>

在多线程环境中,单例模式的实现需要考虑线程安全问题。如果不加以处理,可能会导致多个线程同时创建多个实例。常见的解决方案是使用双重检查锁定(Double-Checked Locking)或使用C++11引入的std::call_once来确保线程安全。

04、懒汉式单例模式(线程安全)

>>>

std::unique_ptr 是 C++11 引入的一种智能指针,用于管理动态分配的对象,并确保在指针超出作用域时自动释放资源。std::unique_ptr 具有独占所有权,即同一时刻只能有一个 std::unique_ptr 指向某个对象。

std::unique_ptr 的特点

  1. 独占所有权std::unique_ptr 不能被复制,只能通过移动语义(std::move)转移所有权。

  2. 自动释放资源:当 std::unique_ptr 超出作用域时,它会自动调用析构函数并释放所管理的对象。

  3. 轻量级std::unique_ptr 的实现非常轻量级,通常只包含一个指针。

在单例模式中的应用

在单例模式中使用 std::unique_ptr 可以确保单例实例在程序结束时自动释放,避免内存泄漏。

// 懒汉式单例模式(线程安全)#include <iostream>#include <mutex>#include <memory>class Singleton {public:    // 获取单例实例    static Singleton& getInstance() {        std::call_once(initFlag, initSingleton);        return *instance;    }    // 禁止拷贝和赋值    Singleton(const Singleton&) = delete;    Singleton& operator=(const Singleton&) = delete;private:    // 私有构造函数    Singleton() {        std::cout << "Singleton instance created." << std::endl;    }    // 初始化单例实例    static void initSingleton() {        instance.reset(new Singleton());    }    // 静态成员变量    static std::unique_ptr<Singleton> instance;    // 静态成员变量初始化标志    static std::once_flag initFlag;};// 静态成员变量初始化std::unique_ptr<Singleton> Singleton::instance;std::once_flag Singleton::initFlag;int main() {    // 获取单例实例    Singleton& s1 = Singleton::getInstance();    Singleton& s2 = Singleton::getInstance();    // s1 和 s2 是同一个实例    if (&s1 == &s2) {        std::cout << "Same instance." << std::endl;    }    return 0;}

05、饿汉式单例模式(线程安全)

>>>

// 饿汉式单例模式(线程安全)#include <iostream>class Singleton {public:    // 获取单例实例    static Singleton& getInstance() {        static Singleton instance;        return instance;    }    // 禁止拷贝和赋值    Singleton(const Singleton&) = delete;    Singleton& operator=(const Singleton&) = delete;private:    // 私有构造函数    Singleton() {        std::cout << "Singleton instance created." << std::endl;    }};int main() {    Singleton& s1 = Singleton::getInstance();    Singleton& s2 = Singleton::getInstance();    // s1 和 s2 是同一个实例    if (&s1 == &s2) {        std::cout << "Same instance." << std::endl;    }    return 0;}

06、区别

>>>

懒汉式饿汉式是两种常见的实现方式,懒汉式在第一次使用时才创建实例,而饿汉式则在程序启动时就创建实例。

总结

>>>

创建型模式(Creational Patterns)

模式名称 | 描述 

单例模式(Singleton) | 确保一个类只有一个实例,并提供一个全局访问点。| 

工厂方法模式(Factory Method) | 定义一个创建对象的接口,但由子类决定实例化哪个类。| 

抽象工厂模式(Abstract Factory) | 提供一个接口,用于创建相关或依赖对象的家族,而不指定具体的类。| 

建造者模式(Builder) | 将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。| 

原型模式(Prototype) | 通过复制现有对象来创建新对象,而不是通过实例化类。|

故我在

点击下方卡片 关注我

↓↓↓

这篇关于C++ | 单例设计模式(懒汉式单例模式源码|饿汉式单例模式)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1146581

相关文章

Linux下如何使用C++获取硬件信息

《Linux下如何使用C++获取硬件信息》这篇文章主要为大家详细介绍了如何使用C++实现获取CPU,主板,磁盘,BIOS信息等硬件信息,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录方法获取CPU信息:读取"/proc/cpuinfo"文件获取磁盘信息:读取"/proc/diskstats"文

Java 正则表达式URL 匹配与源码全解析

《Java正则表达式URL匹配与源码全解析》在Web应用开发中,我们经常需要对URL进行格式验证,今天我们结合Java的Pattern和Matcher类,深入理解正则表达式在实际应用中... 目录1.正则表达式分解:2. 添加域名匹配 (2)3. 添加路径和查询参数匹配 (3) 4. 最终优化版本5.设计思

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

C++中初始化二维数组的几种常见方法

《C++中初始化二维数组的几种常见方法》本文详细介绍了在C++中初始化二维数组的不同方式,包括静态初始化、循环、全部为零、部分初始化、std::array和std::vector,以及std::vec... 目录1. 静态初始化2. 使用循环初始化3. 全部初始化为零4. 部分初始化5. 使用 std::a

C++ vector的常见用法超详细讲解

《C++vector的常见用法超详细讲解》:本文主要介绍C++vector的常见用法,包括C++中vector容器的定义、初始化方法、访问元素、常用函数及其时间复杂度,通过代码介绍的非常详细,... 目录1、vector的定义2、vector常用初始化方法1、使编程用花括号直接赋值2、使用圆括号赋值3、ve

如何高效移除C++关联容器中的元素

《如何高效移除C++关联容器中的元素》关联容器和顺序容器有着很大不同,关联容器中的元素是按照关键字来保存和访问的,而顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的,本文介绍了如何高效移除C+... 目录一、简介二、移除给定位置的元素三、移除与特定键值等价的元素四、移除满足特android定条件的元

Python获取C++中返回的char*字段的两种思路

《Python获取C++中返回的char*字段的两种思路》有时候需要获取C++函数中返回来的不定长的char*字符串,本文小编为大家找到了两种解决问题的思路,感兴趣的小伙伴可以跟随小编一起学习一下... 有时候需要获取C++函数中返回来的不定长的char*字符串,目前我找到两种解决问题的思路,具体实现如下:

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

C/C++错误信息处理的常见方法及函数

《C/C++错误信息处理的常见方法及函数》C/C++是两种广泛使用的编程语言,特别是在系统编程、嵌入式开发以及高性能计算领域,:本文主要介绍C/C++错误信息处理的常见方法及函数,文中通过代码介绍... 目录前言1. errno 和 perror()示例:2. strerror()示例:3. perror(