C++实现单例模式

单例模式:

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

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

1.构造函数私有化

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

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

第一种写法:

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

cpp 复制代码
#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表达式创建堆对象

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

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

代码:

cpp 复制代码
#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. 网页库,倒排索引库都可以使用单例模式

相关推荐
知然20 小时前
鸿蒙 Native API 的封装库 h2lib_arkbinder
c++·arkts·鸿蒙
十五年专注C++开发20 小时前
Qt .pro配置gcc相关命令(三):-W1、-L、-rpath和-rpath-link
linux·运维·c++·qt·cmake·跨平台编译
Cai junhao21 小时前
【Qt】Qt控件
开发语言·c++·笔记·qt
uyeonashi21 小时前
【QT系统相关】QT网络
开发语言·网络·c++·qt
我命由我123451 天前
嵌入式 STM32 开发问题:烧录 STM32CubeMX 创建的 Keil 程序没有反应
c语言·开发语言·c++·stm32·单片机·嵌入式硬件·嵌入式
筏.k1 天前
C++: 类 Class 的基础用法
android·java·c++
C++ 老炮儿的技术栈1 天前
手动实现strcpy
c语言·开发语言·c++·算法·visual studio
一条叫做nemo的鱼1 天前
从汇编的角度揭开C++ this指针的神秘面纱(下)
java·汇编·c++·函数调用·参数传递
ComputerInBook1 天前
理解 C++ 的 this 指针
开发语言·c++·指针·this·this指针
MikeWe1 天前
一文读懂C++移动语义和完美转发
c++