C++实现单例模式

2024-01-07 21:01:16

单例模式:

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

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

文章来源:https://blog.csdn.net/weixin_44143600/article/details/135443544
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。