C++单例模式

简介: C++单例模式

单例模式

1:什么是单例

我的理解:在程序运行期间,只构造一个实例,所有的使用都共享使用该实例

2:如何实现单例

单例的特性:

1:全局唯一的对象 ==》用static成员变量或者作用域特性实现

2:不允许用户去构造 ==》禁用构造函数,但是要保证自己能调用

3:只提供相应的接口,不允许用户修改 ==》禁用相关的拷贝构造等

4:多线程要安全,资源的释放 ==》加锁,同一作用域static对象释放在程序运行结束时调用对应的析构函数

利用static特性,实现单例模式.
  1:静态成员为所有对象共享,不属于某个单个实例
  2:静态成员必须在类外定义,不需要加static,声明时已经加过
  3:类静态成员即可用类名::静态成员或者对象.静态成员来访问
  4:静态成员函数没有隐藏的this指针,不能访问任何非静态成员
  5:静态成员和类的普通成员一样,也有public、protected、private3种访问级别,也可以具有返回值

单例的实现主要依赖static的特性实现!!!

3:编码实现

1: 在栈上控制内存的申请与释放,借助static特性(所有对象共享,不属于某个实例),实现懒汉和饿汉两种模式的单例

饿汉:

#include <iostream>
using namespace std;
class Singleton{
private:
  Singleton() = default;
  Singleton(const Singleton & s) = delete;
  Singleton &operator = (const Singleton &s) = delete;
  ~Singleton(){};
private:
  static Singleton m_sig;
public:
  static Singleton * GetInstence()
  {
    return &m_sig;
  }
  void Print()
  {
    cout<<"Singleton Instence\n ";
  }
};
Singleton Singleton::m_sig; //饿汉
int main()
{
  Singleton::GetInstence()->Print();
  return 0;
}

懒汉: static为整个类服务,而不是某个对象,只初始化一次,而且生命周期延长到整个程序运行结束才释放,全局数据区分配内存

修饰全局变量时,只能在本文件访问

#include <iostream>
using namespace std;
class Singleton{
private:
  Singleton() = default;
  Singleton(const Singleton & s) = delete;
  Singleton &operator = (const Singleton &s) = delete;
  ~Singleton(){};
public:
  static Singleton * GetInstence() //调用这个函数的时候static生效了
  {
    static Singleton m_sig;
    return &m_sig;
  }
  void Print()
  {
    cout<<"Singleton Instence\n ";
  }
};
int main()
{
  Singleton::GetInstence()->Print();
  return 0;
}
2:可以利用static的特性,申请堆内存,相关的实现如下:

如下代码,借助static管理堆内存,但明显发现,new出来的资源是没有释放的,

#include <iostream>
#include <mutex>
using namespace std;
class Singleton{
private:
  Singleton() = default;
  Singleton(const Singleton & s) = delete;
  Singleton &operator = (const Singleton &s) = delete;
  ~Singleton(){};
public:
  //对静态成员操作,所以控制成static
  static Singleton * GetInstence()
  {
    if(Singleton::m_sig_instance == NULL)
    {
      m_mutex.lock();
      if(Singleton::m_sig_instance == NULL)
      {
        m_sig_instance = new Singleton();
      }
      m_mutex.unlock();
    }
  }
  void Print()
  {
    cout<<"Singleton Instence.\n ";
  }
private:
  static Singleton * m_sig_instance;
  static std::mutex m_mutex;
};
Singleton * Singleton::m_sig_instance = NULL;
std::mutex Singleton::m_mutex;
int main()
{
  Singleton::GetInstence()->Print();
  return 0;
}

借助static的栈内存特性和类的作用域会调用析构函数,在类的作用域内用static特性实现资源的释放:

#include <iostream>
#include <mutex>
using namespace std;
class Singleton{
private:
  Singleton() = default;
  Singleton(const Singleton & s) = delete;
  Singleton &operator = (const Singleton &s) = delete;
  ~Singleton(){};
  class FreeSingleton
  {
    public:
      ~FreeSingleton()
      {
        cout<<"start free singletion \n";
        if(m_sig_instance != NULL)
        {
          cout<<"free singletion \n";
          delete m_sig_instance;
          m_sig_instance = NULL;
        }
      }
  };
public:
  //对静态成员操作,所以控制成static
  static Singleton * GetInstence()
  {
    if(Singleton::m_sig_instance == NULL)
    {
      m_mutex.lock();
      if(Singleton::m_sig_instance == NULL)
      {
        m_sig_instance = new Singleton();
      }
      m_mutex.unlock();
    }
  }
  void Print()
  {
    cout<<"Singleton Instence.\n ";
  }
private:
  static Singleton * m_sig_instance;
  static std::mutex m_mutex;
  static FreeSingleton m_freed;
};
Singleton * Singleton::m_sig_instance = NULL;
std::mutex Singleton::m_mutex;
//借助static 栈的特性,通过析构释放对应的内存 注意这里的类型和static变量的作用域取值
Singleton::FreeSingleton Singleton::m_freed; 
int main()
{
  Singleton::GetInstence()->Print();
  return 0;
}
目录
相关文章
|
2月前
|
设计模式 安全 测试技术
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
62 0
|
2月前
|
设计模式 安全 测试技术
【C++】—— 单例模式详解
【C++】—— 单例模式详解
|
4月前
|
C++
C++实现单例模式-多种方式比较
单例模式,面试中经常被问到,但是很多人只会最简单的单例模型,可能连多线程都没考虑到,本文章从最简单的单例,到认为是最佳的单例模式实现方式,单例模式没有什么知识点,直接上源码
50 0
|
7月前
|
设计模式 存储 安全
设计模式之单例模式(C++)
设计模式之单例模式(C++)
|
7月前
|
设计模式 安全 Java
特殊类设计及单例模式(C++)
特殊类设计及单例模式(C++)
65 1
|
7天前
|
设计模式 Java C++
【C++高阶(八)】单例模式&特殊类的设计
【C++高阶(八)】单例模式&特殊类的设计
|
7天前
|
设计模式 安全 编译器
【代码片段】【C++】C++11线程安全单例模式
【代码片段】【C++】C++11线程安全单例模式
13 1
|
2月前
|
设计模式 存储 缓存
【ffmpeg C++ 播放器优化实战】优化你的视频播放器:使用策略模式和单例模式进行视频优化
【ffmpeg C++ 播放器优化实战】优化你的视频播放器:使用策略模式和单例模式进行视频优化
58 0
|
2月前
|
设计模式 存储 缓存
设计模式之单例模式(C++)
设计模式之单例模式(C++)
25 2
|
4月前
|
设计模式 安全 编译器
c++单例模式-6种单例层层迭代优化
6种单例模式,层层迭代优化
17 1