设计模式-01 设计模式单例模式

设计模式-01 设计模式单例模式

目录

设计模式-01 设计模式单例模式

1定义

2.内涵

3.使用示例

4.具体代码使用实践

5.注意事项

6.最佳实践

7.总结


1 定义


单例模式是一种设计模式,它确保一个类只能被实例化一次。它通过在类内部创建类的唯一实例并提供一个全局访问点来实现这一点。


优点:

全局访问:单例对象可以从应用程序的任何地方访问。
资源节约:它只创建一个对象,从而节省了内存和资源。
线程安全性:如果单例对象正确实现,它可以是线程安全的,这意味着它可以在多线程环境中安全地使用。


2.内涵

单例模式在 C++ 设计模式中具有以下内涵:

封装:单例类的内部状态和实现细节对客户端代码是隐藏的。这使你可以自由地更改类的实现,而无需影响使用它的代码。
全局访问:单例对象可以在应用程序的任何地方访问,这使得它非常适合存储全局状态或提供公共服务。
资源管理:由于单例模式确保只创建一个对象,因此它可以帮助管理资源,例如数据库连接或文件句柄。

3.使用示例

单例模式,有很多种实现方式,下面是几种实现方式的介绍。

延迟加载

class Singleton {
private:static Singleton* instance;Singleton() {}public:static Singleton* getInstance() {if (instance == nullptr) {instance = new Singleton();}return instance;}
};


饿汉式

class Singleton {
private:static Singleton* instance = new Singleton();Singleton() {}public:static Singleton* getInstance() {return instance;}
};

C++11 实现单例模式代码

class Singleton {
private:Singleton() {}  // 私有构造函数防止直接实例化Singleton(const Singleton&) = delete;  // 私有拷贝构造函数防止复制Singleton& operator=(const Singleton&) = delete;  // 私有赋值运算符防止赋值static Singleton* instance;  // 静态成员变量存储单例实例public:static Singleton& getInstance() {// 双重检查锁定,确保线程安全if (instance == nullptr) {std::lock_guard<std::mutex> lock(mutex);if (instance == nullptr) {instance = new Singleton();}}return *instance;}private:static std::mutex mutex;  // 互斥锁用于线程安全
};// 在类外初始化静态成员变量
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mutex;

4.具体代码使用实践
#include <iostream>class Singleton {
public:// Static method to access the singleton instancestatic Singleton& getInstance(){// If the instance doesn't exist, create itif (!instance) {instance = new Singleton();}return *instance;}// Public method to perform some operationvoid someOperation(){std::cout<< "Singleton is performing some operation."<< std::endl;}// Delete the copy constructor and assignment operatorSingleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;private:// Private constructor to prevent external instantiationSingleton(){std::cout << "Singleton instance created."<< std::endl;}// Private destructor to prevent external deletion~Singleton(){std::cout << "Singleton instance destroyed."<< std::endl;}// Private static instance variablestatic Singleton* instance;
};// Initialize the static instance variable to nullptr
Singleton* Singleton::instance = nullptr;int main()
{// Access the Singleton instanceSingleton& singleton = Singleton::getInstance();// Use the Singleton instancesingleton.someOperation();// Attempting to create another instance will not work// Singleton anotherInstance; // This line would not// compilereturn 0;
}

5.注意事项


C++11 实现单例模式的注意事项和潜在问题:

1. 线程安全性:

确保单例类的实现是线程安全的,以避免并行访问时出现数据损坏。使用互斥锁或其他同步机制来保护共享数据。


2. 静态局部变量初始化顺序未定义:

在 C++11 中,静态局部变量(例如 Singleton::instance)的初始化顺序是未定义的。为了确保单例类的正确初始化,请使用双重检查锁定模式。


3. 循环引用和内存泄漏:

如果单例类持有其他对象的引用,请确保这些引用不会导致循环引用并导致内存泄漏。可以使用智能指针或弱引用来管理引用。


4. 异常安全性:

单例类的构造函数应该抛出异常安全,这意味着在构造函数抛出异常后,单例类的状态应该保持有效。可以使用 RAII 技术来实现异常安全性。


5. 过度使用:

避免过度使用单例模式。只在需要全局访问和资源管理的情况下才使用它。过度使用单例模式可能会导致设计僵化和测试困难。

6.最佳实践
  • 使用双重检查锁定:这是一种可靠的方法来确保线程安全的单例实现。
  • 使用 RAII 技术:这可以确保在异常情况下正确清理资源。
  • 仔细管理引用:使用智能指针或弱引用来避免循环引用和内存泄漏。
  • 仅在必要时使用单例模式:考虑其他设计模式,例如工厂模式或依赖注入,以实现全局访问和资源管理。
  • 进行彻底的测试:编写测试用例来验证单例实现的正确性和线程安全性。

7.总结

C++11 中的单例模式通过双重检查锁定和 RAII 技术实现线程安全的惰性实例化,确保全局访问和资源管理。在实现上,这比起低版本的来说,预言特性给我们更加灵活的操作性

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

飞书API(6):使用 pandas 处理数据并写入 MySQL 数据库

一、引入 上一篇了解了飞书 28 种数据类型通过接口读取到的数据结构&#xff0c;本文开始探讨如何将这些数据写入 MySQL 数据库。这个工作流的起点是从 API 获取到的一个完整的数据&#xff0c;终点是写入 MySQL 数据表&#xff0c;表结构和维格表结构类似。在过程中可以有不同…

完美解决AttributeError: module ‘backend_interagg‘ has no attribute ‘FigureCanvas‘

遇到这种错误通常是因为matplotlib的后端配置问题。在某些环境中&#xff0c;尤其是在某些特定的IDE或Jupyter Notebook环境中&#xff0c;可能会因为后端配置不正确而导致错误。错误信息提示 module backend_interagg has no attribute FigureCanvas 意味着当前matplotlib的后…

首页最新 多IP浏览器防关联:如何配置多个独立且稳定的IP地址?

在互联网时代&#xff0c;IP地址的重要性不言而喻。然而&#xff0c;IP关联问题却成为一项令人担忧的隐私和安全挑战。针对这个问题&#xff0c;多IP浏览器是一种解决方案&#xff0c;可以帮助用户单独配置多个独立且稳定的IP地址&#xff0c;有效地防止IP关联。 一、IP关联是…

【Python小练】求斐波那契数列第n个数

题目 输出斐波那契数列第n个数。 分析 首先我们要知道&#xff0c;斐波那契数列&#xff0c;这个数列从第三位开始等于前两个数的和&#xff0c;要知道数列第n个数&#xff08;n>2&#xff09;&#xff0c;就要知道其前两相的值&#xff0c;着就需要用到递归了。来看一下吧…

开源、轻量、易用的服务器实时监控工具:哪吒探针

本文首发于只抄博客&#xff0c;欢迎点击原文链接了解更多内容。 前言 哪吒探针是一个开源、轻量、易用的服务器监控、运维工具&#xff0c;它有以下几个特点&#xff1a; 一键安装&#xff1a;可以一键安装面板与 Agent&#xff0c;并且支持 Linux、Windows、MacOS、OpenWRT…

纯血鸿蒙APP实战开发——发布图片评论

介绍 本示例将通过发布图片评论场景&#xff0c;介绍如何使用startAbilityForResult接口拉起相机拍照&#xff0c;并获取相机返回的数据。 效果图预览 使用说明 通过startAbilityForResult接口拉起相机&#xff0c;拍照后获取图片地址。 实现思路 创建CommentData类&#…

VSCode 配置 CMake

VSCode 配置 C/C 环境的详细过程可参考&#xff1a;VSCode 配置 C/C 环境 1 配置C/C编译环境 方案一 如果是在Windows&#xff0c;需要安装 MingW&#xff0c;可以去官网(https://sourceforge.net/projects/mingw-w64/)下载安装包。 注意安装路径不要出现中文。 打开 windows…

虚析构与纯虚析构

这里的new Cat("Tom"&#xff09;是由于基类函数中的构造函数里面带有string变量 1. 法一:利用虚函数&#xff0c;虚化基类中的析构函数 virtual ~Animal() { cout << "动物的析构函数调用" << endl; } 2. 法二:利用纯…

VitePress 构建的博客如何部署到 Netlify 平台?

VitePress 构建的博客如何部署到 Netlify 平台&#xff1f; 前言 之前写了篇文章【使用 Vitepress 构建博客并部署到 github 平台】&#xff0c;有个老哥说 github page 访问太慢了&#xff0c;希望放到 Netlify 平台上面。 咱也没部署过&#xff0c;就试了一下&#xff0c;发…

低功耗数字IC后端设计实现典型案例| UPF Flow如何避免工具乱用Always On Buffer?

下图所示为咱们社区低功耗四核A7 Top Hierarchical Flow后端训练营中的一个案例&#xff0c;设计中存在若干个Power Domain&#xff0c;其中Power Domain2(简称PD2)为default Top Domain&#xff0c;Power Domain1&#xff08;简称PD1&#xff09;为一个需要power off的domain&…

【再探】设计模式—抽象工厂及建造者模式

抽象工厂模式和建造者模式都属于创建型模式。两者都能创建对应的对象&#xff0c;而创建者模式更侧重于创建复杂对象&#xff0c;将对象的创建过程封装起来&#xff0c;让客户端不需要知道对象的内部细节。 1 抽象工厂模式 需求&#xff1a; 在使用工厂方法模式时&#xff0…

Postgresql 从小白到高手 十一 :数据迁移ETL方案

文章目录 Postgresql 数据迁移ETL方案1、Pg 同类型数据库2 、Pg 和 不同数据库 Postgresql 数据迁移ETL方案 1、Pg 同类型数据库 备份 : pg_dump -U username -d dbname -f backup.sql插入数据&#xff1a; psql -U username -d dbname -f backup.sqlpg_restore -U username…

【Godot4.2】自定义Todo清单类 - myTodoList

概述 在写myList类的时候&#xff0c;就想到可以写一个类似的Todo清单类。 基础思路 本质还是在内部维护一个数组&#xff0c;在其基础上进行增删改查操作的封装为了方便存储数据&#xff0c;编写一个自定义内置类TodoItem&#xff0c;内部数组就变成了Array[TodoItem]类型的…

JENKINS 安装,学习运维从这里开始

Download and deployJenkins – an open source automation server which enables developers around the world to reliably build, test, and deploy their softwarehttps://www.jenkins.io/download/首先点击上面。下载Jenkins 为了学习&#xff0c;从windows开始&#x…

mysql-sql练习-5-行列互转

目录 成绩单 简单互转 需求 多行转多列 分组 判断 聚合 理解 分组 合并 逆向需求 多列转多行 输出 合并 abc 去重 合并 拆分 需求 建表 多行转多列 逆向需求 多列转多行 拆分 按长度 拆分 按个数 成绩单 简单互转 需求 多行转多列 分组 判断 聚合 with tmp as(--…

【快速入门 LVGL】-- 5、Gui Guider界面移植到STM32工程

上篇&#xff0c;我们已学习&#xff1a;【快速入门 LVGL】-- 4、显示中文 工程中添加了两个按钮作示范。运行效果如图&#xff1a; 本篇&#xff1a;把Gui Guider设计好的界面&#xff0c;移植到STM32工程。 特别地&#xff1a; 在使用Gui Guider进行界面设计时&#xff0c;应…

如何在Linux上安装Python?2024Python安装教程

在Linux上安装Python并不难&#xff0c;对于Ubuntu或Debian系统&#xff0c;使用命令sudo apt install python3&#xff1b;对于CentOS、Red Hat或Fedora系统&#xff0c;使用命令sudo yum install python3。 如何在Linux上安装Python&#xff1f; 确切的安装步骤有所不同&am…

LabVIEW 2024安装教程(附免费安装包资源)

鼠标右击软件压缩包&#xff0c;选择“解压到LabVIEW.2024”。 返回解压后的文件夹&#xff0c;鼠标右击“ni_labview-2024”选择“装载”。 鼠标右击“Install”选择“以管理员身份运行”。 点击“我接受上述2条许可协议”&#xff0c;然后点击“下一步”。 点击“下一步”。 …

用html画一个四叶草

<!DOCTYPE html> <html lang"en" > <head> <meta charset"UTF-8"> <title>四叶草</title> <link href"" rel"stylesheet"> <link rel"stylesheet" href"css/style.css&q…

xLua详解

目录 环境准备xLua导入 C#调用LuaLua解析器Lua文件加载重定向Lua解析管理器全局变量的获取全局函数的获取List和Dictionary映射table类映射table接口映射tableLuaTable映射table Lua调用C#准备工作Lua使用C#类Lua调用C#枚举Lua使用C# 数组 List 字典数组List字典 Lua使用C#扩展…