「C/C++」C++ 设计模式 之 单例模式(Singleton)

news2024/11/23 12:07:11

在这里插入图片描述

✨博客主页
何曾参静谧的博客
📌文章专栏
「C/C++」C/C++程序设计
📚全部专栏
「VS」Visual Studio「C/C++」C/C++程序设计「UG/NX」BlockUI集合
「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发
「QT」QT5程序设计「File」数据文件格式「PK」Parasolid函数说明

目录

    • C++单例模式详解
      • 一、单例模式的定义
      • 二、单例模式的实现方式
      • 三、单例模式的应用场景
      • 四、注意事项

C++单例模式详解

在C++编程中,设计模式是开发者在软件设计过程中总结出的可复用解决方案,旨在解决常见的设计问题。单例模式(Singleton Pattern)是这些设计模式中的一种,它确保一个类只有一个实例,并提供一个全局访问点来获取该实例。本文将深入探讨C++中的单例模式,包括其定义、实现方式、应用场景以及注意事项。

一、单例模式的定义

单例模式的核心思想是确保一个类只有一个实例,并提供一个全局访问点来访问该实例。这个模式在需要控制资源访问、实现全局状态管理或确保某些操作只执行一次时非常有用。

二、单例模式的实现方式

在C++中,单例模式的实现通常涉及以下几个步骤:

  1. 私有化构造函数:防止外部通过new关键字创建类的多个实例。
  2. 静态私有成员变量:用于存储类的唯一实例。
  3. 静态公有成员函数:提供一个全局访问点来获取类的唯一实例。这个函数通常被称为getInstanceInstance

以下是一个简单的C++单例模式实现示例:

#include <iostream>
#include <memory>

class Singleton {
public:
    // 禁用拷贝构造函数和赋值运算符,防止复制实例
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

    // 静态公有成员函数,用于获取类的唯一实例
    static Singleton& getInstance() {
        // 局部静态变量在第一次调用时初始化,且只初始化一次
        static Singleton instance;
        return instance;
    }

    // 其他成员函数
    void doSomething() {
        std::cout << "Doing something in Singleton instance." << std::endl;
    }

private:
    // 私有化构造函数,防止外部创建实例
    Singleton() {
        std::cout << "Singleton instance created." << std::endl;
    }

    // 私有化析构函数(可选),防止外部删除实例
    ~Singleton() {
        std::cout << "Singleton instance destroyed." << std::endl;
    }
};

int main() {
    // 通过getInstance获取单例实例并调用其成员函数
    Singleton& singleton = Singleton::getInstance();
    singleton.doSomething();

    // 尝试再次获取实例(应该是同一个实例)
    Singleton& anotherSingleton = Singleton::getInstance();
    anotherSingleton.doSomething();

    // 注意:不需要(也不应该)手动删除单例实例
    // delete &singleton; // 错误:会导致未定义行为

    return 0;
}

在这个示例中,Singleton类通过私有化其构造函数和析构函数(虽然析构函数私有化是可选的,但有助于防止外部删除实例),以及提供静态的getInstance函数来确保类的唯一实例。getInstance函数内部使用了一个局部静态变量来存储类的实例,这个变量在第一次调用getInstance时初始化,并且只初始化一次,从而保证了单例性。

三、单例模式的应用场景

单例模式在C++中有广泛的应用场景,包括但不限于:

  • 全局配置管理:用于存储和管理应用程序的全局配置信息。
  • 资源池:如数据库连接池、线程池等,用于管理有限资源的分配和回收。
  • 日志记录器:用于集中管理日志记录的实例,确保日志记录的一致性和可维护性。
  • 状态管理器:用于管理应用程序的全局状态,如用户登录状态、应用程序的当前模式等。

四、注意事项

在使用单例模式时,需要注意以下几点:

  • 线程安全:在多线程环境中,需要确保getInstance函数的线程安全性。可以通过使用互斥锁(如std::mutex)来实现。
  • 内存管理:虽然局部静态变量在程序结束时会自动销毁,但在长时间运行的应用程序中,需要注意单例实例的生命周期管理,避免内存泄漏。
  • 单例的销毁:在大多数情况下,不需要(也不应该)手动删除单例实例。然而,在某些情况下(如单元测试后清理资源),可能需要提供一种机制来显式销毁单例实例。这通常可以通过将单例实例封装在一个智能指针(如std::unique_ptr)中来实现,但需要注意这可能会增加代码的复杂性。
  • 依赖注入:在大型项目中,过度使用单例模式可能会导致代码紧密耦合和难以测试。在这种情况下,可以考虑使用依赖注入等设计模式来替代或补充单例模式。

总之,单例模式是一种简单而强大的设计模式,在C++编程中有广泛的应用。然而,在使用时需要谨慎考虑其适用性和潜在的问题,以确保代码的正确性、可维护性和可扩展性。


在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2230309.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【前端基础】CSS基础

目标&#xff1a;掌握 CSS 属性基本写法&#xff0c;能够使用文字相关属性美化文章页。 01-CSS初体验 层叠样式表 (Cascading Style Sheets&#xff0c;缩写为 CSS&#xff09;&#xff0c;是一种 样式表 语言&#xff0c;用来描述 HTML 文档的呈现&#xff08;美化内容&#…

【Oracle】空格单字符通配符查询匹配失败

问题 在进行模糊查询的时候&#xff0c;通过全局任意字符串匹配出含有两个字刘姓的人&#xff0c;但是通过刘_不能匹配出结果。 解决 检查后发现&#xff0c;姓名中包含空格 SELECT * FROM student WHERE TRIM(sname) LIKE 刘_;第一种解决方案就是查询的时候进行去空格处理&a…

查看多个通道32bit音频pcm数据

本文分析一个32位多通道pcm数据&#xff0c;一方面简单解释一下pcm数据格式&#xff0c;另外一方面看清楚实际数据的精度是多少。 说明&#xff1a;这是一个alsa采集到的10路32bit的pcm数据。 使用bc打开&#xff0c;16进制数据显示如下图&#xff1a; 图中左边是一个10通道32…

【语义分割|代码解析】CMTFNet-2: CNN and Multiscale Transformer Fusion Network 用于遥感图像分割!

【语义分割|代码解析】CMTFNet-2: CNN and Multiscale Transformer Fusion Network 用于遥感图像分割&#xff01; 【语义分割|代码解析】CMTFNet-2: CNN and Multiscale Transformer Fusion Network 用于遥感图像分割&#xff01; 文章目录 【语义分割|代码解析】CMTFNet-2: …

Webpack 配置module.css报错Uncaught TypeError: Cannot read properties of undefined

我的项目结构如下: 入口文件是index.jsx&#xff0c;组件Button.jsx使用了样式button.module.css .btn {background-color: #4CAF50;border: none;color: white; padding: 15px 32px;text-align: center;text-decoration: none;display: inline-block;font-size: 16px;margin:…

Redis(2):内存模型

一、Redis内存统计 工欲善其事必先利其器&#xff0c;在说明Redis内存之前首先说明如何统计Redis使用内存的情况。 在客户端通过redis-cli连接服务器后&#xff08;后面如无特殊说明&#xff0c;客户端一律使用redis-cli&#xff09;&#xff0c;通过info命令可以查看内存使用情…

Docker打包自己项目推到Docker hub仓库(windows10)

一、启用Hyper-V和容器特性 1.应用和功能 2.点击程序和功能 3.启用或关闭Windows功能 4.开启Hyper-V 和 容器特性 记得重启生效&#xff01;&#xff01;&#xff01; 二、安装WSL2&#xff1a;写文章-CSDN创作中心https://mp.csdn.net/mp_blog/creation/editor/143057041 三…

python如何安装扩展包

1、扩展包 Python安装额外的扩展包&#xff0c;一般使用anconda进行管理。 1、1安装命令 一般我们在anconda中通过pip install 包名 的方式进行安装&#xff0c;不过由于这些包在国外下载&#xff0c;因此需要配置合适的镜像促使其下载更快。 1、2 镜像源配置 1、2、1 一次…

【风冷换热器设计及计算

某空气调节工程需要将33.3kg/s的空气&#xff0c;由干球温度t123℃、相对湿度ψ160&#xff05;&#xff0c;冷却到干球温度t212℃、相对湿度ψ290&#xff05;&#xff0c;冷凝器出口为40℃的饱和液体&#xff0c;制冷剂采用R22&#xff0c;试设计一台直接蒸发式空气冷却器。 …

LabVIEW程序员赚钱不仅限于上班

LabVIEW程序员拥有多种途径来实现财富增值&#xff0c;而不仅仅局限于传统的全职工作。以下是一些他们可以利用自身技能和专业知识实现更高财务收益的方法&#xff1a; 1. 专注领域的自由职业与合同工作 制造、科研、医疗技术等行业都需要LabVIEW的专业知识。通过自由职业&…

C++ shared_ptr 动态内存

C shared_ptr 动态内存 智能指针 为了更加容易的使用动态内存&#xff0c;新的标准库提供了智能指针&#xff0c;用来管理动态对象&#xff0c;智能指针的行为类似常规指针&#xff0c;重要的区别是他负责自动释放所指的对象。新标准库提供的智能指针的区别在于管理底层指针的…

动态代理:面向接口编程,屏蔽RPC处理过程

RPC远程调用 使用 RPC 时&#xff0c;一般的做法是先找服务提供方要接口&#xff0c;通过 Maven把接口依赖到项目中。在编写业务逻辑的时候&#xff0c;如果要调用提供方的接口&#xff0c;只需要通过依赖注入的方式把接口注入到项目中&#xff0c;然后在代码里面直接调用接口…

Spring Boot:打造动态定时任务,开启灵活调度之旅

一、描述 在 Spring Boot 中设置动态定时任务是一种非常实用的功能&#xff0c;可以根据实际需求在运行时动态地调整定时任务的执行时间、频率等参数。以下是对 Spring Boot 设置动态定时任务的简单介绍&#xff1a; 1、传统定时任务的局限性 在传统的 Spring Boot 定时任务…

Chrome与夸克谁更节省系统资源

在当今数字化时代&#xff0c;浏览器已经成为我们日常生活中不可或缺的一部分。无论是工作、学习还是娱乐&#xff0c;我们都依赖于浏览器来访问互联网。然而&#xff0c;不同的浏览器在性能和资源消耗方面存在差异。本文将探讨Chrome和夸克两款浏览器在系统资源消耗方面的表现…

react的antd-mobile使用Steps显示物流

antd-mobile的图标&#xff0c;是需要安装依赖的 step如果只有一个步骤是不会展示的&#xff0c;代码里面的标题那块可以看出来 尝试了很多遍测试发现一直不显示&#xff0c;查询后发现是这个组件的本身设置的原因 那么就算你只展示一个那么也要写两个step&#xff0c;第二个…

AI-基本概念-多层感知器模型/CNN/RNN/自注意力模型

1 需求 神经网络 …… 深度学习 …… 深度学习包含哪些神经网络&#xff1a; 全连接神经网络卷积神经网络循环神经网络基于注意力机制的神经网络 2 接口 3 CNN 在这个示例中&#xff1a; 首先定义了一个简单的卷积神经网络SimpleCNN&#xff0c;它包含两个卷积层、两个池…

链表详解(一)

目录 顺序表的问题及思考链表链表的概念及结构链表的分类单链表的实现链表功能实现遍历链表void SLTprint(SLNode* phead)代码 创造新节点SLNode* CreateNode(SLNDataType x)代码 顺序表的问题及思考 中间/头部的插入删除&#xff0c;时间复杂度为O(N),效率低,但是尾部插入效率…

【MongoDB】Windows/Docker 下载安装,MongoDB Compass的基本使用、NoSQL、MongoDB的基础概念及基础用法(超详细)

文章目录 Windows下载MongoDB Compass使用NoSQL的基本概念MongoDB常用术语MongoDB与RDBMS区别MongoDB的CRUD 更多相关内容可查看 Docker安装MongoDB可查看&#xff1a;Docker-安装MongoDB Windows下载 官网下载地址&#xff1a;https://www.mongodb.com/try/download/communi…

uni-app发起请求以及请求封装,上传及下载功能(六)

文章目录 一、发起网络请求1.使用及封装2. https 请求配置自签名证书3.拦截器 二、上传下载1.上传 uni.uploadFile(OBJECT)2. 下载 uni.downloadFile(OBJECT) 一、发起网络请求 uni-app中内置的uni.request()已经很强大了&#xff0c;简单且好用。为了让其更好用&#xff0c;同…

C语言 | Leetcode C语言题解之第526题优美的排列

题目&#xff1a; 题解&#xff1a; int countArrangement(int n) {int f[1 << n];memset(f, 0, sizeof(f));f[0] 1;for (int mask 1; mask < (1 << n); mask) {int num __builtin_popcount(mask);for (int i 0; i < n; i) {if (mask & (1 <<…