单例模式

概述

单例模式是一个创建型设计模式,一个类只会创建一个对象。

由于只有一个对象,所以不能够通过new来创建对象,因此类的构造函数得是private的

由于不能够new出对象,所以类内部需要提供一个函数来获取对象,这个函数和对象都是属于类的,而不是对象,因此这个函数和唯一 的对象都得是static的,并且对象是private类型的,函数是public类型的

 

创建单例的基本步骤:

1. 构造函数私有化,避免外部使用构造函数来创建对象

2. 增加静态私有的当前类的指针变量

3. 提供静态的public接口,可以让用户获取单例

 

单例模式分为懒汉和饿汉:

1.懒汉式

优点:

第一次调用的时候才初始化,避免内存浪费

缺点:

必须加锁才能够保证单例,加锁会影响效率

实现:

class SingletonLazy

{
private:
  SingletonLazy(){
  std::cout << "single lazy!" << std::endl;
}
public:
  static SingletonLazy* getInstatce()

  {
    if( NULL == lazy )

    {
      lazy = new SingletonLazy;
    }
    return lazy;
  }
private:
  static SingletonLazy* lazy;
};
//类外初始化
SingletonLazy* SingletonLazy::lazy = NULL;

 

2.饿汉式

优点:

不需要加锁,执行效率高,线程安全的

缺点:

不管是不是用都会初始化,浪费内存

实现:

class SingletonHungry

{
private:
  SingletonHungry(){
  std::cout << "single hungry!" << std::endl;
}
public:
  static SingletonHungry* getInstatce()

  {
  return hungry;
  }
//SingletonHungry类退出以后会自动析构free_single,
//从而调用FreeSingle的析构函数来释放单例
//其实类退出时会自动释放单例不需要该类
  class FreeSingle

  {
  ~FreeSingle()

  {
    if( NULL != hungry )

    {
      delete hungry;
      hungry = NULL;
    }
  }  
};
private:
  static SingletonHungry* hungry;
  static FreeSingle free_single;
};
//类外初始化
SingletonHungry* SingletonHungry::hungry = new SingletonHungry;

 

 

局部静态变量方法:

// 局部静态变量
class Singleton

{
public:
// 使用指针而不是引用是为了避免拷贝构造函数进行拷贝
// Singleton single = Singleton::getInstance();
  static Singleton* getInstance()

  {
  static Singleton instance;
  return &instance;
  }
private:  
  Singleton() 

  {
    std::cout << "局部静态方式" << std::endl;
  }
// 如果需要getInstance 返回引用,
// 也可以通过重载赋值运算符和拷贝构造函数,这两个函数不需要具体的实现
  Singleton(Singleton const & single);
  Singleton& operator = (const Singleton& single);
};

线程安全问题:

  在多线程中,由于懒汉式存在多个线程调用同一个对象资源,存在线程不安

全问题,需要使用同步机制来解决该问题饿汉模式不存在线程安全问题,在

加载类的时候就实例化对象了

 

线程安全模式:

class SingletonMulThread

{
private:
  SingletonMulThread()

  {
  std::cout << "single MulThread!" << std::endl;
  }
public:
  static SingletonMulThread* getInstatce()

  {
    if( NULL == single_multhread )

    {
      std::lock_guard<std::mutex> lock(mutex);
      if( NULL == single_multhread )

      {
        single_multhread = new SingletonMulThread;
      }
    }
  return single_multhread;
  }
private:
  static SingletonMulThread* single_multhread;
  static mutex mutex;
};
//类外初始化
SingletonMulThread* SingletonMulThread::single_multhread = NULL;
mutex SingletonMulThread::mutex;

 

posted @ 2021-08-12 21:30  一大堆豆子  阅读(41)  评论(0编辑  收藏  举报