C++实现单例模式

news2024/11/16 6:57:55

单例模式:

一种设计模式,它的目的是确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。它适用于需要全局唯一的对象或资源的情况。

23种设计模式种最简单最常见的一种(高频考点) 要求:通过一个类只能创建一个对象

1.构造函数私有化

2.定义静态的成员函数,其调用只能通过类名进行调用。

可以看到其地址一样,这就达到了我们要的效果

第一种写法:

引用+静态(将创建的单一对象放到全局静态区)(不推荐)

#include <iostream>

using std::cout;
using std::endl;
//单例模式的实现方式一:不推荐使用
class Point{
public:
    //实现了构造函数私有,即不可通过外部去创建对象
   //因为只有对象才能调用成员函数,故将该函数设计为静态函数
   //使其只能通过类名::进行调用
  static  Point  &getInstance()
   {
       //我们用引用的话,因为Point pt(1,2)是一个临时变量
       //其生命周期随着函数的消失而消失
       //故我们用static将其定义为全局静态对象即可返回引用
       /* static Point pt(1,2); */
       static Point pt;
       return pt;
   }
  void init(int x,int y)
  {
      _ix=x;
      _iy=y;
  }

    void print()
    {
        cout<<"("<<_ix
            <<","<<_iy
            <<")"<<endl;
    }
//私有化之后的构造函数只能在类内调用
private:
    Point(int ix=0 ,int iy=0)
    : _ix(ix)
      ,_iy(iy)
    {
        cout<<"Point(int,int)"<<endl;
    }
    int _ix;
    int _iy;
};
//全局对象也不能创建
/* Point pt3(1,3); */
void test(){
    //该对象不可能是一个栈对象
    /* Point pt1(1,2);//创建无数个对象 */
    /* Point pt2(3,4);//在语法上不能编译通过 */
    Point &pt = Point::getInstance();
    
    Point &pt2 = Point::getInstance();
    Point &pt3 = Point::getInstance();
    cout<<"pt:"<<&pt<<endl;
    cout<<"pt2:"<<&pt2<<endl;
    cout<<"pt3:"<<&pt3<<endl;
    pt.print();
    pt2.print();
}
int main()
{
    test();
    return 0;
}

第二种方式:

第一次调用getInstance函数时,直接new表达式创建堆对象

后续的调用直接返回第一次创建的对象即可

第二种写法是静态指针+静态数据成员(返回指针地址)

代码:

#include <iostream>

using std::cout;
using std::endl;
//单例模式的实现方式二:推荐使用
class Point{
public:
    //第一次调用getInstance函数时,直接new表达式创建堆对象
    //后续的调用直接返回第一次创建的对象即可
  static  Point  *getInstance()
   {
       if(_pInstance == nullptr)
       {
       _pInstance = new Point;
       }
       return _pInstance;
   }
  static void destory()
  {
      if(_pInstance)
      {
          delete _pInstance;
          _pInstance = nullptr;
      }
  }
  void init(int x,int y)
  {
      _ix=x;
      _iy=y;
  }

    void print()
    {
        cout<<"("<<_ix
            <<","<<_iy
            <<")"<<endl;
    }
private:
Point(int ix=0 ,int iy=0)
    : _ix(ix)
      ,_iy(iy)
    {
        cout<<"Point(int,int)"<<endl;
}

~Point()
{
    cout<<"~Point()"<<endl;
}
//私有化之后的构造函数只能在类内调用
private:
    
    int _ix;
    int _iy;
    static Point *_pInstance;
};
//在全局静态区进行初始化
Point * Point::_pInstance = nullptr;
//全局对象也不能创建
/* Point pt3(1,3); */
void test(){
    //该对象不可能是一个栈对象
    /* Point pt1(1,2);//创建无数个对象 */
    /* Point pt2(3,4);//在语法上不能编译通过 */
    Point *pt = Point::getInstance();
    
    Point *pt2 = Point::getInstance();
    cout<<"pt:"<<pt<<endl;
    cout<<"pt2:"<<pt2<<endl;
    pt->print();
    pt2->print();

    //不能让该表达式编译通过
    /* delete  pt; */
    /* delete  pt2; //功能上可以实现,但是在代码形式上显得很突兀,不够优雅 */
    Point::destory();//完成对空间的回收
}
int main()
{
    test();
    return 0;
}

具体步骤:

  1. 在类中定义一个静态的指向本类型的指针 (该指针用来存储第一次调用静态成员函数getInstance创建出来的对象)

  2. 将构造函数私有化(不能在类之外直接调用)

  3. 在public区域,定义一个静态成员函数 (第一次调用该函数时,在该函数中new一个对象,后续的调用都是直接返回第一次创建的对象。)

应用场景:

  1. 单例模式可以用来替换全局对象类型

  2. 配置文件中的信息可以存储在单例对象中

  3. 网页库,倒排索引库都可以使用单例模式

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

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

相关文章

移动通信原理与关键技术学习(3)

1.什么是相干解调&#xff1f;什么是非相干解调&#xff1f;各自的优缺点是什么&#xff1f; 相干解调需要在接收端有一个与发送端一样的载波&#xff08;同样的频率和相位&#xff09;&#xff0c;在接收端的载波与发送端载波进行互相关操作&#xff0c;去除载波的影响。相干…

ssm使用web工程的相关知识

不使用框架创建web的两种方式&#xff08;这里是idea2022.3.2版&#xff09; 第一种&#xff1a;项目右键点击&#xff1a;add Framwork support选择框架进行创建。 操作步骤&#xff1a; 使用这种方式创建可能会存在的问题&#xff1a; 如果你创建web框架前&#xff1a;在…

【Flutter 开发实战】Dart 基础篇:常见的数据类型

Dart 支持许多数据类型&#xff0c;包括我们常见的 Numbers&#xff08;数值类型&#xff09;、Strings&#xff08;字符串类型&#xff09;、Booleans&#xff08;布尔类型&#xff09;&#xff0c;也支持一些包括 Collections&#xff08;集合类型&#xff09;、Records&…

嵌入式项目——平衡小车(1)

焊接 驱动板需要焊接的如上图。 陀螺仪8pin排母电机两路排线插口。(个别同学需要焊接)两个电池仓,注意电池仓分正反。 安装 底部电池板 4个 双通尼龙柱M3*224个 尼龙螺钉M3*6电机驱动板

环境搭建 之 Ubuntu 安装

ubuntu-releases-20.04.6安装包下载_开源镜像站-阿里云ubuntu-releases-20.04.6安装包是阿里云官方提供的开源镜像免费下载服务&#xff0c;每天下载量过亿&#xff0c;阿里巴巴开源镜像站为包含ubuntu-releases-20.04.6安装包的几百个操作系统镜像和依赖包镜像进行免费CDN加速…

Matplotlib for C++不完全手册

matplotlib-cpp是Matplotlib&#xff08;MPL&#xff09;为C提供的一个用于python的matplotlib绘图库的C包装器。它的构建类似于Matlab和matplotlib使用的绘图API。 However, the function signatures might differ and Matplotlib for C does not support the full functional…

【嵌入式】Makefile 学习笔记记录 | 嵌入式Linux

文章目录 前言一、Makefile的引入——最简单的gcc编译过程二、Makefile的规则三、Makefile的语法3.1、通配符3.2、假想目标 .phony3.3、即时变量 延时变量 四、Makefile的函数4.1、foreach4.2、filter4.3、wildcard4.4、patsubst 五、Makefile升级5.1、包含头文件在内的依赖关系…

商品期货交易中的强行平仓:交易所的规定和风险控制

在商品期货交易中&#xff0c;保证金充足的情况下&#xff0c;一般不会被强行平仓。然而&#xff0c;有几种情况可能会导致强行平仓的发生&#xff1a; 1 持仓超过交易所限仓规定&#xff1a;交易所会设定限仓规定&#xff0c;限制每位投资者的持仓数量。如果超过限仓规定&…

如何使用 CMake 来构建一个共享库(动态库)

tutorial_4/CMakeLists.txt # 声明要求的 cmake 最低版本 cmake_minimum_required( VERSION 2.8 )# 声明一个 cmake 工程 project( HelloSLAM )add_subdirectory(src)tutorial_4/src/CMakeLists.txt #工程添加多个特定的头文件搜索路径 include_directories(include)set(LIBR…

静态路由、代理ARP

目录 静态路由静态路由指明下一跳和指明端口的区别代理ARP 我们知道&#xff0c;跨网络通信需要路由 路由有三种类型&#xff1a; 1.直连路由。 自动产生的路由&#xff0c;当网络设备连接到同一网络时&#xff0c;他们可以自动学习到对方的存在。自动学习相邻网络设备的直连信…

python编程从入门到实践(3+4)操作列表+if语句

文章目录 第四章 列表操作4.1遍历整个列表&#xff1a;可能会发生变化的数值&#xff0c;列表可修改4.1.2遍历中的缩进 4.3创建数值列表4.3.1 使用range&#xff08;&#xff09;函数range&#xff08;i&#xff0c;m&#xff09;输出从i到m-1range(m) 打印从0到m-1 4.3.1 使用…

Java集合框架概念详解

目录 1. 什么是Java集合框架&#xff1f;2. 常用接口介绍3. 常用实现类介绍4. 集合框架的应用场景 前言&#xff1a; Java集合框架是Java编程中最重要的工具之一。它提供了一套强大而灵活的数据结构和算法&#xff0c;用于存储和操作数据。本文将详细介绍Java集合框架的概念、常…

数据结构—环形缓冲区

写在前面&#xff0c;2023年11月开始进入岗位&#xff0c;工作岗位是嵌入式软件工程师。2024年是上班的第一年的&#xff0c;希望今年收获满满&#xff0c;增长见闻。 数据结构—环形缓冲区 为什么要使用环形数组&#xff0c;环形数组比起原来的常规数组的优势是什么&#xf…

CLIP is Also an Efficient Segmenter

表1 复现结果–Seed&#xff1a;70.7245673447014&#xff0c;dCRF&#xff1a;74.85437742935268 误差小于0.5个点&#xff0c;可以接受 表4 复现结果–训练300轮&#xff0c;Val&#xff1a;58.76741354153312&#xff0c;Test&#xff1a;59.18210 感想 VOC全部复现完成&…

spring事务默认传播机制REQUIRED的试验(手动开启事务代码+feign远程调用)

transactional注解&#xff0c;默认啥都不指定的时候&#xff0c;我们使用的就是PROPAGATION_REQUIRED这种方式。 PROPAGATION_REQUIRED:业务方法需要在一个事务中运行&#xff0c;如果方法运行时&#xff0c;已处在一个事务中&#xff0c;那么就加入该事务&#xff0c;否则自…

Linux操作系统基础(12):Linux的Shell解释器

1. Shell的介绍 在Linux中&#xff0c;Shell 是一种命令行解释器&#xff0c;它是用户与操作系统内核之间的接口&#xff0c;它负责解释用户输入的命令&#xff0c;并将其转换成系统调用或其他操作系统能够执行的指令。 Shell 提供了一种交互式的方式来与操作系统进行通信&am…

关于使用统一服务器,vscode和网页版jupyter notebook的交互问题

autodl 查看虚拟环境 在antodl上租借了一个服务器&#xff0c;通过在网页上运行jupyter notebook和在vscode中运行&#xff0c;发现环境都默认的是miniconda3。 conda info --envs 当然环境中所有的包都是一样的。 要查看当前虚拟环境中安装的所有包&#xff0c;可以使用以…

C++流媒体服务器 ZLMediaKit框架ZLToolKit源码解读

ZLMediaKit是国人开发的开源C流媒体服务器&#xff0c;同SRS一样是主流的流媒体服务器。 ZLToolKit是基于C11的高性能服务器框架&#xff0c;和ZLMediaKit是同一个作者&#xff0c;ZLMediaKit正是使用该框架开发的。 ZLMediaKit开源地址&#xff1a;https://github.com/ZLMedi…

CP_AutoSar目录

目录 一、RTE二、模式和状态管理三、BSW四、工具链相关五、杂项六、优化相关 一些笔记和日常记录。有部分未包含在此目录中。 一、RTE [AutoSar]基础部分 RTE 01 介绍 [AutoSar]基础部分 RTE 02 S/R Port 显式/隐式 [AutoSar]基础部分 RTE 03 C/S Port 同步/异步 [AutoSar]基…

VELO维乐携手【晓饰记】创始人胡晓,引领潮流新饰界!

不知道大家还记不记得2023年维乐带着自己满满的诚意闪现英伦时尚之都为全世界带来了一场无与伦比的视觉盛宴&#xff01;而依照维乐固有的执念&#xff0c;从不会让自己止步的精神&#xff0c;维乐又带着自己的维乐坐垫找到了CoCo胡晓&#xff0c;【晓饰记】的首饰品牌创始人、…