C++设计模式|创建型 1.单例模式

1.什么是单例模式?

单例模式的的核⼼思想在创建类对象的时候保证⼀个类只有⼀个实例,并提供⼀个全局访问点来访问这个实例。

  • 只有⼀个实例的意思是,在整个应⽤程序中,只存在该类的⼀个实例对象,⽽不是创建多个相同类型的对象。
  • 全局访问点的意思是,为了让其他类能够获取到这个唯⼀实例,该类提供了⼀个全局访问点(通常是⼀个静态⽅法),通过这个⽅法就能获得实例。

 2.单例设计模式的优点

  • 全局控制:保证只有⼀个实例,这样就可以严格的控制客户怎样访问它以及何时访问它,简单的说就是对唯⼀实例的受控访问。
  • 节省资源:也正是因为只有⼀个实例存在,就避免多次创建了相同的对象,从⽽节省了系统资源,⽽且多个模块还可以通过单例实例共享数据。
  • 懒加载:单例模式可以实现懒加载,只有在需要时才进⾏实例化,能够提⾼程序的性能。

3. 单例设计模式的要求

  • 私有的构造函数:C++类的私有权限使得构造函数只能在类内部被访问,防⽌外部代码直接创建类的实例。
  • 私有的静态实例变量:C++中类的静态成员(变量或函数)归类所有,是类的所有实例所共享的。将实例变量设为静态,表明这个类的实例变量唯一。设为私有,辨明该实例在类外必须通过公有的接口来获得。
  • 公有的静态方法getInstance():这个就是上面所述的获取唯一实例的借口。静态也使其具有唯一的性质。

 4.单例模式的实现

按照实例创建的时机,单例模式有着多种实现方式,包括懒汉式、饿汉式等。

饿汉式:在类加载时就已经完成了实例的创建,不管后面创建的实例有没有使用,先创建再说,所以叫做 “饿汉”。

懒汉式:只有在请求实例时才会创建,如果在首次请求时还没有创建,就创建一个新的实例,如果已经创建,就返回已有的实例,意思就是需要使用了再创建,所以称为“懒汉”。

多线程环境下,由于饿汉式在程序启动阶段就完成了实例的初始化,因此不存在多个线程同时尝试初始化实例的问题,但是懒汉式中多个线程同时访问 getInstance() 方法并且在同一时刻检测到实例没有被创建,就可能会同时创建实例,从而导致多个实例被创建,这种情况下我们可以采用一些同步机制,例如使用互斥锁来确保在任何时刻只有一个线程能够执行实例的创建。

5.C++代码实战

小明的购物车icon-default.png?t=N7T8https://kamacoder.com/problempage.php?pid=1074

题目描述:

小明去了一家大型商场,拿到了一个购物车,并开始购物。请你设计一个购物车管理器,记录商品添加到购物车的信息(商品名称和购买数量),并在购买结束后打印出商品清单。(在整个购物过程中,小明只有一个购物车实例存在)。

输入描述

输入包含若干行,每行包含两部分信息,分别是商品名称和购买数量。商品名称和购买数量之间用空格隔开。

输出描述

输出包含小明购物车中的所有商品及其购买数量。每行输出一种商品的信息,格式为 "商品名称 购买数量"。

输入示例

Apple 3
Banana 2
Orange 5

输出示例 

Apple 3
Banana 2
Orange 5

提示信息 

本道题目请使用单例设计模式: 

使用私有静态变量来保存购物车实例

使用私有构造函数防止外部直接实例化

思路分析:

题目要求使用单例模式设计一个购物车管理器,那么这个管理器的类就是需要进行单例设置的类。包括私有的构造函数、私有的静态实例以及公有的实例获取方法接口。

代码实现:

#include<iostream>
#include<map>
#include<string>
using namespace std;class ShoppingManager{
private://私有的构造函数防止类外实例化ShoppingManager(){}//使用map作为购物车存放商品名级商品数量map<string,int> cart;public://公有的静态接口函数,获取实例static ShoppingManager&  getInstance(){//静态实例。由于构造函数私有,所以该实例也算是必须类内调用构造函数才能得到。带有私有的含义static ShoppingManager instance;  return instance;}//析构函数~ShoppingManager(){}//将商品添加到购物车。const保证数据不会误改,引用&避免拷贝void addGoods(const string& name,const int& num){cart[name] += num;  //+=保证同名商品数量叠加而不是重写覆盖}//查看购物车.  注意const的作用void viewCart() const {//正常访问// for(auto it = cart.begin(); it!= cart.end();++it)  {//     cout<<it->first<<" "<<it->second<<endl;// }//避免迭代器修改的访问。注意,迭代器类似指针,所以访问map的内容用->// for(map<string,int>::const_iterator it = cart.cbegin(); it!=cart.cend();++it)// {//     cout<<it->first<<" "<<it->second<<endl;// }//如果是范围for语句,则得到的是map的每一个成员,属于pair类型,用.点来访问内容for( const auto  & member: cart){cout<<member.first<<" "<<member.second<<endl;}}};int main()
{string name;int num;//按行读数据,可以使用while循环配合cinwhile(cin>>name>>num){//由于单例模式的构造函数私有,无法直接点用构造函数实例化,所以无法通过对象调用getInstance//因此,可以使用类名::getInstance()的方式来获取单例ShoppingManager & myCart = ShoppingManager::getInstance();myCart.addGoods(name,num);}// 输出购物车内容。const ShoppingManager& myCart = ShoppingManager::getInstance();myCart.viewCart();return 0;
}

    由于实例是静态的,所以它的生存周期会在程序运行结束才销毁,且唯一,存放在全局区,因此即使第一次创建实例时是在while循环里面,第二次再使用getInstance获取它时,仍能获取到这个唯一的实例,其数据为最近一次更改后的数据。构造函数也旨在第一次构建实例时调用了,myCart.viewCart()前面的那句的getInstance代码并没有调用构造函数。读者可以在构造函数里打印一句话用以验证这一点。

6.应用场景

  • 资源共享

        多个模块共享某个资源的时候,可以使用单例模式,比如说应用程序需要一个全局的配置管理器来存储和管理配置信息、亦或是使用单例模式管理数据库连接池。

  • 只有一个实例

        当系统中某个类只需要一个实例来协调行为的时候,可以考虑使用单例模式, 比如说管理应用程序中的缓存,确保只有一个缓存实例,避免重复的缓存创建和管理,或者使用单例模式来创建和管理线程池。

  • 懒加载

        如果对象创建本身就比较消耗资源,而且可能在整个程序中都不一定会使用,可以使用单例模式实现懒加载

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

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

相关文章

【JAVA基础篇教学】第八篇:Java中List详解说明

博主打算从0-1讲解下java基础教学&#xff0c;今天教学第八篇&#xff1a;Java中List详解说明。 在 Java 编程中&#xff0c;List 接口是一个非常常用的集合接口&#xff0c;它代表了一个有序的集合&#xff0c;可以包含重复的元素。List 接口提供了一系列操作方法&#xff0c;…

72V电瓶电压降5V1.5A恒压WT7039

72V电瓶电压降5V1.5A恒压WT7039 WT6039是一款12V至72V宽电压降压DC-DC转换器芯片&#xff0c;集成了开关控制、参考电源、误差放大器等多重功能&#xff0c;并具备过热、限流和短路保护。它能在广泛输入功率下实现2A连续输出电流&#xff0c;并通过编程调整输出电压。适用于高…

文心一言

文章目录 前言一、首页二、使用总结 前言 今天给大家带来百度的文心一言,它基于百度的文心大模型,是一种全新的生成式人工智能工具。 一、首页 首先要登录才能使用,左侧可以看到以前的聊天历史 3.5的目前免费用,但是4.0的就需要vip了 二、使用 首先在最下方文本框输入你想要搜…

ArrayList,Vector,LinkedList内存解析

1.ArrayList (1). 特点 : 实现了List接口&#xff0c;存储有序的&#xff0c;可重复的数据.底层使用Object[]数组存储.线程不安全.(底层方法未用synchronized修饰.) (2). 版本解析 : <i> : JDK7版本 ArrayList<String> list &#xff1d;new ArrayList<&…

npm问题合集以及npm常规操作整理

问题一&#xff1a;npm install 卡在“sill idealTree buildDeps“ 可以尝试将网络切换为其他网络&#xff0c;我的是这么解决的。可以尝试重新设置镜像。 问题二&#xff1a;npm install 项目依赖报WARN deprecated 原因 依赖版本问题&#xff0c;下载最新版本。 解决方案 …

做多 与 做空 概念解析

坐多&#xff1a;低买高卖 阶段一&#xff1a;借钱->低价时买货>得货 阶段二&#xff1a;高价时卖货 > 得更多的钱 阶段三&#xff1a;还钱 >余钱 多空&#xff1a;高卖低买 阶段一&#xff1a;借货->高价时卖货>得钱 阶段二&#xff1a;低价时买货 …

ElasticSearch中使用bge-large-zh-v1.5进行向量检索(一)

一、准备 系统&#xff1a;MacOS 14.3.1 ElasticSearch&#xff1a;8.13.2 Kibana&#xff1a;8.13.2 BGE是一个常见的文本转向量的模型&#xff0c;在很多大模型RAG应用中常常能见到&#xff0c;但是ElasticSearch中默认没有。BGE模型有很多版本&#xff0c;本次采用的是bg…

Lua语法(四)——协程

参考链接: 系列链接: Lua语法(一) 系列链接: Lua语法(二)——闭包/日期和时间 系列链接: Lua语法(三)——元表与元方法 系列链接: Lua语法(四)——协程 系列链接: Lua语法(五)——垃圾回收 系列链接: Lua语法(六)——面相对象编程 Lua语法 四——协程 简介正文协程coroutine.c…

vue和react通用后台管理系统权限控制方案

1. 介绍 在任何企业级应用中&#xff0c;尤其是后台管理系统&#xff0c;权限控制是一个至关重要的环节。它确保了系统资源的安全性&#xff0c;防止非法访问和操作&#xff0c;保障业务流程的正常进行。本文件将详细解析后台管理系统中的权限控制机制及其实施策略。 那么权限…

写代码的修养

看山是山&#xff0c;看水是水 此境界 对业务的思考是浅层的&#xff0c;代码写的不通用&#xff0c;扩展性差&#xff0c;表现在无设计模式 看山不是山&#xff0c;看水不是水 此境界 对业务的思考是中层的&#xff0c;代码写的通用&#xff0c;扩展性好&#xff0c;表现为…

算法思想总结:分治思想

一、颜色划分 . - 力扣&#xff08;LeetCode&#xff09; class Solution { public:void sortColors(vector<int>& nums) {//三路划分的思想int nnums.size();int left-1, rightn,cur0;while(cur<right){if(nums[cur]0) swap(nums[left],nums[cur]);else if(nums…

关于openai和chatgpt、gpt-4、PyTorch、TensorFlow 两者和Transformers的关系

近两年&#xff0c;随着人工智能的火爆&#xff0c;不论通过哪个渠道&#xff0c;相信我们都听说过openai、gpt等这类名词&#xff0c;那么它们到底是什么意思&#xff0c;请看下文。 openai:是一家人工智能公司&#xff1b; openai-api&#xff1a;是openai提供的api&#xf…

ChatGPT加持,需求分析再无难题

简介 在实际工作过程中&#xff0c;常常需要拿到产品的PRD文档或者原型图进行需求分析&#xff0c;为产品的功能设计和优化提供建议。 而使用ChatGPT可以很好的帮助分析和整理用户需求。 实践演练 接下来&#xff0c;需要使用ChatGPT 辅助我们完成需求分析的任务 注意&…

GMSSL-通信

死磕GMSSL通信-C/C++系列(一) 最近再做国密通信的项目开发,以为国密也就简单的集成一个库就可以完事了,没想到能有这么多坑。遂写下文章,避免重复踩坑。以下国密通信的坑有以下场景 1、使用GMSSL guanzhi/GmSSL进行通信 2、使用加密套件SM2-WITH-SMS4-SM3 使用心得 ​…

电动汽车原理视频笔记

看到了一个讲的不错的系列视频 新能源维修猿老罗的个人空间-新能源维修猿老罗个人主页-哔哩哔哩视频 新能源汽车上的安全防护系统就是这么多&#xff01;-绝缘检测等_哔哩哔哩_bilibili 新能源汽车居然是这样上电的-高低压上下电详细流程_哔哩哔哩_bilibili

机器学习和深度学习-- 李宏毅(笔记与个人理解)Day 14

Day 14 Classfication (short version) 二分类的时候 用sigmoid 那不就是 logistic 回归嘛&#xff08;softmax 的二分类等价&#xff09; Loss 哦 今天刚学的 &#xff0c;KL散度 &#xff0c;看来cross-entropy 和KL散度是等价的咯~ 我感觉我的直觉没错 这里MSE离得很远的时候…

php未能在vscode识别?

在设置里搜php&#xff0c;找到settings.json&#xff0c;设置你的安装路径即可。 成功

HubSpot如何通过自动化和优化客户服务流程?

在当今竞争激烈的市场环境中&#xff0c;提供卓越的客户服务体验已经成为企业赢得客户忠诚、推动业务增长的关键所在。HubSpot&#xff0c;作为一款领先的客户关系管理软件&#xff0c;通过自动化和优化客户服务流程&#xff0c;为企业带来了革命性的服务体验提升。 HubSpot通…

【今日bug】在本地创建容器,进入后快速退出

容器已启动但立即退出&#xff1a; 根据 STATUS 列显示的 Exited (1) 5 seconds ago&#xff0c;容器确实已被启动&#xff0c;但几乎立刻就退出了。退出状态码为 1&#xff0c;通常表示在容器内部执行的命令&#xff08;这里是 /bin/bash&#xff09;遇到非零退出状态&#xf…

【opencv】示例-grabcut.cpp 使用OpenCV库的GrabCut算法进行图像分割

left mouse button - set rectangle SHIFTleft mouse button - set GC_FGD pixels CTRLleft mouse button - set GC_BGD pixels 这段代码是一个使用OpenCV库的GrabCut算法进行图像分割的C程序。它允许用户通过交互式方式选择图像中的一个区域&#xff0c;并利用GrabCut算法尝试…