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;
}
目录
相关文章
|
7月前
|
设计模式 安全 测试技术
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
152 0
|
7月前
|
设计模式 安全 测试技术
【C++】—— 单例模式详解
【C++】—— 单例模式详解
|
7月前
|
C++
C++实现单例模式-多种方式比较
单例模式,面试中经常被问到,但是很多人只会最简单的单例模型,可能连多线程都没考虑到,本文章从最简单的单例,到认为是最佳的单例模式实现方式,单例模式没有什么知识点,直接上源码
103 0
|
2月前
|
C++
C++单例模式
C++中使用模板实现单例模式的方法,并通过一个具体的类A示例展示了如何创建和使用单例。
35 2
|
7月前
|
设计模式 安全 算法
【C++入门到精通】特殊类的设计 | 单例模式 [ C++入门 ]
【C++入门到精通】特殊类的设计 | 单例模式 [ C++入门 ]
57 0
|
4月前
|
安全 C++
C++ QT 单例模式
C++ QT 单例模式
79 0
|
4月前
|
设计模式 安全 IDE
C++从静态类型到单例模式
C++从静态类型到单例模式
40 0
|
5月前
|
设计模式 安全 C++
C++一分钟之-C++中的设计模式:单例模式
【7月更文挑战第13天】单例模式确保类只有一个实例,提供全局访问。C++中的实现涉及线程安全和生命周期管理。基础实现使用静态成员,但在多线程环境下可能导致多个实例。为解决此问题,采用双重检查锁定和`std::mutex`保证安全。使用`std::unique_ptr`管理生命周期,防止析构异常和内存泄漏。理解和正确应用单例模式能提升软件的效率与可维护性。
69 2
|
6月前
|
设计模式 存储 缓存
C++ -- 单例模式
**摘要:** 单例模式确保一个类仅有一个实例,并提供全局访问点。为了实现单例,构造函数通常设为私有,通过静态成员函数来创建和返回实例。两种常见实现是饿汉模式(在类加载时创建实例,线程安全但可能导致不必要的内存占用)和懒汉模式(首次使用时创建,可能需线程同步)。拷贝构造函数和赋值运算符通常被禁用来防止额外实例的创建。单例模式适用于资源管理、缓存和线程池等场景。在C++中,静态成员变量和函数用于存储和访问单例实例,保证其生命周期与程序相同。
|
7月前
|
安全 程序员 C语言
从C语言到C++_37(特殊类设计和C++类型转换)单例模式(下)
从C语言到C++_37(特殊类设计和C++类型转换)单例模式
61 5