当前位置: 首页 > news >正文

c++设计模式之单例模式

介绍

一个类无论创建多少对象都只能得到一个实例

A* p1=new A();
A* p2=new A();
A* p3=new A();

如上述代码中,我们通过new运算符创建出了类A的三个对象实例,而我们现在要做的是,如何设计类A,使得上述代码运行之后永远只产生同一个对象实例

设计方法

1.将构造函数声明为私有

        我们知道,一个类对象是通过这个类的构造函数创建的,因此,我们首先要拒绝用户使用构造函数。

也许有人会问,我们在类中不写构造函数不行么?

确实不行,构造函数与普通成员函数的区别之一就在于,即使你不写,编译器也会自动为你创建一个构造函数

因此,这一步的目的在于:拒绝编译和用户使用构造函数创建对象

class Singleton
{
public:
private:Singleton(){};
};

2.在类中自行定义一个static对象

由于我们拒绝用户和编译器自行创建对象,因此我们必须自己在类中定义一个对象,且其类型必须为static的,因为只有static类型的变量才属于这个类,而不是属于某个对象

class Singleton
{
public:
private:static Singleton instance;Singleton(){};
};

声明为private的原因是,防止用户对其进行修改。

3.定义一个外部可以访问到该static对象实例的接口

由于上述定义的实例对象是private的,因此我们需要定义一个公共接口,来供外部用户进行访问

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

该接口声明为static的原因是,用户此时还没有创建出实例,而普通成员函数的调用必须通过对象进行,因此如果想要用户使用这个函数,就必须要将其声明为static的

4.拒绝对象的拷贝和赋值

至此,我们已经完成了一个半成品,也就是说,这个时候我们要使用Sington对象,就必须通过其中的static成员函数getInstance来获取,而该函数返回的对象实例永远都是同一个实例

#include<iostream>
using namespace std;class Singleton
{
public:static Singleton* getInstance(){return &instance;}
private:static Singleton instance;Singleton(){};
};void test()
{/*此时,s1,s2,s3所指向的对象实例都是类中自己创建的那个instance*/Singleton* s1=Singleton::getInstance();Singleton* s2=Singleton::getInstance();Singleton* s3=Singleton::getInstance();
}int main()
{test();return 0;
}

但还有个问题是,编译器还会为我们创建拷贝构造函数和拷贝赋值运算符,因此,当我们进行对象拷贝操作的时候,这个实例对象就不是“单例”的了

Singleton t=*p1;//此时编译器会自行创造出一个拷贝构造函数,从而创建出一个p1的副本

而解决这个问题的办法,上述也说明过,只需将其声明为私有即可


class Singleton
{
public:static Singleton* getInstance(){return &instance;}
private:static Singleton instance;Singleton(){};Singleton(const Singleton&)=delete;Singleton& operator=(const Singleton&)=delete;
};

饿汉式单例模式

还没有获取对象实例,对象实例就已经创建了

上述最后的代码就是饿汉式单例模式,由于对象实例在类A是static的,因此我们在还没有调用接口在获取该对象的时候,它就已经存在了

class Singleton
{
public:static Singleton* getInstance(){return &instance;}
private:static Singleton instance;Singleton(){};Singleton(const Singleton&)=delete;Singleton& operator=(const Singleton&)=delete;
};

因此,它的特点是

  • 优点
    • 实现简单,线程安全:在类加载时就创建了实例,不存在多线程并发访问的问题
    • 执行效率高:没有加锁、同步等额外操作
  • 缺点
    • 内存浪费:类加载时即创建实例,如果单例对象占用大量资源或者初始化耗时较长,会导致程序启动变慢。
    • 无法延迟加载即使没有使用到该单例对象,也会被创建

懒汉式单例模式

唯一的实例,只有在第一次获取它的时候才会创建

由于饿汉式单例模式的缺陷,有了懒汉式单例模式的出现,也就是对象延迟加载,看代码


class Singleton
{
public:static Singleton* getInstance(){// return &instance;if(instance==nullptr){instance=new Singleton();}return instance;}
private:static Singleton *instance;Singleton(){};Singleton(const Singleton&)=delete;Singleton& operator=(const Singleton&)=delete;
};

最大的区别在于

我们将类中创建的对象实例声明为指针类型,这样当类加载的时候,内存中存在的是一个指针,而指针变量的大小永远都是固定的

	static Singleton *instance;

其次,再看接口函数的实现

	static Singleton* getInstance(){// return &instance;if(instance==nullptr){instance=new Singleton();}return instance;}

该函数在调用时,首先会判断instance是否为nullptr,而instance为nullptr说明用户是第一次在代码中创建该实例,此时就new一个实例对象,返回给用户,而后续用户再创建实例对象时,instance就不为空了,直接返回即可

相关文章:

c++设计模式之单例模式

介绍 一个类无论创建多少对象&#xff0c;都只能得到一个实例 A* p1new A(); A* p2new A(); A* p3new A(); 如上述代码中&#xff0c;我们通过new运算符创建出了类A的三个对象实例&#xff0c;而我们现在要做的是&#xff0c;如何设计类A&#xff0c;使得上述代码运行之后永远…...

Git学习笔记(第5章):Git团队协作机制

目录 5.1 团队内协作 5.2 跨团队协作 Git进行版本控制都是在本地库操作的。若想使用Git进行团队协作&#xff0c;就必须借助代码托管中心。 5.1 团队内协作 问题引入&#xff1a;成员1&#xff08;大佬&#xff09;利用Git在宿主机上初始化本地库&#xff0c;完成代码的整体…...

Python 面向对象绘图(Matplotlib篇-16)

Python 面向对象绘图(Matplotlib篇-16)         🍹博主 侯小啾 感谢您的支持与信赖。☀️ 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ�…...

Linux开机自动挂载window密码有转义字符的共享文件夹

项目上遇到需要自动挂载windows共享盘到linux系统中&#xff0c;由于windows密码有英文逗号(,)&#xff0c;被linux识别成了参数分隔符&#xff0c;在网上找了很多办法都不行&#xff0c;后来通过这种方式完美解决&#xff0c;linux系统是centos8.4文章阅读操作时间在5分钟左右…...

Redis(四)

1、Redis的单/多线程 1.1、单线程 其实直接说Redis什么单线程或者是多线程&#xff0c;不太准确&#xff0c;在redis的4.0版主之前是单线程&#xff0c;然后在之后的版本中redis的渐渐改为多线程。 Redis是单线程主要是指Redis的网络IO和键值对读写是由一个线程来完成的&#…...

一文解读ISO26262安全标准:术语

一文解读ISO26262安全标准&#xff1a;术语 做汽车行业的人&#xff0c;都知道安全标准ISO26262&#xff0c;但是仔细说说它到底讲的是什么&#xff1f;好像又说不出来&#xff0c;这是个玄之又玄的话题&#xff0c;笔者试图将这份标准以简明扼要、并且容易理解的形式梳理出来&…...

使用stable diffussion插件StableSR将图片高清放大

一&#xff1a;需要安装的插件 1、StableSR&#xff0c;项目地址&#xff1a;https://github.com/pkuliyi2015/sd-webui-stablesr 不过国内没什么用&#xff0c;访问不了&#xff0c;可以用下面的国内镜像&#xff1a; https://gitee.com/han51535/sd-webui-stablesr.git 这…...

ActiveMQ:专注消息传递,助您构建高效稳定的系统

在数字化世界的今天&#xff0c;应用程序和系统之间的通信变得日益重要&#xff0c;为了确保数据能够在不同的服务和组件之间高效、可靠地传输&#xff0c;消息队列技术应运而生。 Apache ActiveMQ 作为一种流行的开源消息队列技术&#xff0c;为企业级应用提供了强大的支持&am…...

小程序样例1:简单待办列表

基本功能&#xff1a; 显示所有待办列表&#xff08;点击不同的文本进行显示&#xff09; 没完成的待办 已完成的待办 新建待办test 清除待办foo 代码js文件&#xff1a; //index.js //获取应用实例 const app getApp(); Page({data: {todo: ,todos: [{"id": 1474…...

Jvm相关知识(面试高级必备)

类的实例化顺序 先静态、先父后子 先静态&#xff1a;父静态>子静态 优先级&#xff1a;父类>子类 静态代码块>非静态代码块>构造函数 一个类的实例化过程&#xff1a; ①&#xff0e;父类的static代码块&#xff0c;当前类的static; ②&#xff0e;顺序执行…...

android 常规log的查看与抓取

ProtoLog开关 在代码中我们经常看见ProtoLog打印的log&#xff0c;如下&#xff1a; ProtoLog.i(WM_DEBUG_ANIM, "Animation start delayed for %s", mAnimatable);这种log正常情况不会显示&#xff0c;因此我们需要打开开关&#xff0c;其格式为&#xff1a; adb …...

【SpringBoot】—— 如何创建SpringBoot工程

SpringBoot简化了Spring应用的初始搭建和开发过程。 工程创建 新建模块 出现java: 错误: 无效的源发行版&#xff1a;18这样的错误&#xff0c; 修改pom.xml文件 出现以下信息&#xff0c;即运行成功 修改默认端口 创建application.yml文件 内容&#xff1a; server:port:…...

2018年认证杯SPSSPRO杯数学建模A题(第二阶段)海豚与沙丁鱼全过程文档及程序

2018年认证杯SPSSPRO杯数学建模 基于聚类分析的海豚捕食合作策略 A题 海豚与沙丁鱼 原题再现&#xff1a; 沙丁鱼以聚成大群的方式来对抗海豚的捕食。由于水下光线很暗&#xff0c;所以在距离较远时&#xff0c;海豚只能使用回声定位方法来判断鱼群的整体位置&#xff0c;难…...

C# tcp客户端字符串(图片名称)+ 图片数据打包,发送到服务端;服务端接收到数据后解析数据包

在C#中&#xff0c;要将字符串和图片数据打包发送到服务端&#xff0c;并在服务端解析这些数据&#xff0c;可以按照以下步骤进行&#xff1a; 客户端打包数据 1、创建一个自定义的数据结构来保存字符串和图片数据。 2、将字符串转换为字节数组。 3、将图片数据转换为字节数组。…...

【机组】算术逻辑单元带进位运算实验的解密与实战

​&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《机组 | 模块单元实验》⏰诗赋清音&#xff1a;云生高巅梦远游&#xff0c; 星光点缀碧海愁。 山川深邃情难晤&#xff0c; 剑气凌云志自修。 ​ 目录 &#x1f33a;一、 实验目…...

axios query传数组参数的格式

在 Axios 中&#xff0c;当你需要传递数组参数时&#xff0c;可以使用以下几种方式进行格式化&#xff1a; 使用 paramsSerializer 将数组转换为逗号分隔的字符串&#xff1a; import axios from axios;import qs from qs;const arrayParams [param1, param2, param3];axios.…...

2018年认证杯SPSSPRO杯数学建模B题(第一阶段)动态模糊图像全过程文档及程序

2018年认证杯SPSSPRO杯数学建模 B题 动态模糊图像 原题再现&#xff1a; 人眼由于存在视觉暂留效应&#xff0c;所以看运动的物体时&#xff0c;看到的每一帧画面都包含了一段时间内 (大约 1/24 秒) 的运动过程&#xff0c;所以这帧画面事实上是模糊的。对电影的截图来说&…...

qt学习:Qfile文件类

目录 功能 读接口 参数说明 返回值 例子 写接口 参数说明 QString转为QByteArray 其他接口 功能 该类是一个用户读写文件io口&#xff0c;它继承于QFileDevice 读接口 qint64 read(char *data,qint64 maxSize)// 一次读取maxSize大小的数据存放在以data…...

从 GPT1 - GPT4 拆解

从 GPT1 - GPT4 拆解 从 GPT1 - GPT4GPT1&#xff1a;更适用于文本生成领域GPT2&#xff1a;扩展数据集、模型参数&#xff0c;实现一脑多用&#xff08;多个任务&#xff09;GPT3&#xff1a;元学习 大力出奇迹InstructGPT&#xff1a;指示和提示学习 人工反馈强化学习 RLHF…...

Python项目——计算器(PySide6+Pyinstaller)

1、介绍 使用python编写一个计算器&#xff0c;可以实现基本的运算。【注】该项目最终还有一些细小的bug没有完善&#xff0c;例如符号可以一直输入。 2、实现 使用pyCharm创建一个新的项目。 2.1、设计UI 使用Qt designer设计一个UI界面&#xff0c;保存ui文件&#xff0…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

DiscuzX3.5发帖json api

参考文章&#xff1a;PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下&#xff0c;适配我自己的需求 有一个站点存在多个采集站&#xff0c;我想通过主站拿标题&#xff0c;采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...

Python常用模块:time、os、shutil与flask初探

一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...

UE5 音效系统

一.音效管理 音乐一般都是WAV,创建一个背景音乐类SoudClass,一个音效类SoundClass。所有的音乐都分为这两个类。再创建一个总音乐类&#xff0c;将上述两个作为它的子类。 接着我们创建一个音乐混合类SoundMix&#xff0c;将上述三个类翻入其中&#xff0c;通过它管理每个音乐…...