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

相关文章

C++中实现调试日志输出

《C++中实现调试日志输出》在C++编程中,调试日志对于定位问题和优化代码至关重要,本文将介绍几种常用的调试日志输出方法,并教你如何在日志中添加时间戳,希望对大家有所帮助... 目录1. 使用 #ifdef _DEBUG 宏2. 加入时间戳:精确到毫秒3.Windows 和 MFC 中的调试日志方法MFC

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规

Java汇编源码如何查看环境搭建

《Java汇编源码如何查看环境搭建》:本文主要介绍如何在IntelliJIDEA开发环境中搭建字节码和汇编环境,以便更好地进行代码调优和JVM学习,首先,介绍了如何配置IntelliJIDEA以方... 目录一、简介二、在IDEA开发环境中搭建汇编环境2.1 在IDEA中搭建字节码查看环境2.1.1 搭建步

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象