C++实现设计模式之单例模式

1. 单例模式

1.1 为什么提出了单例模式

有一些情况下,我们建立的类是属于工具性质的,无需存储太多自身的数据,在这种情况下,每一次去new一次对象,都会增大系统的开销。其实只需要实例化一次对象就可以了。

1.2 单例模式的定义

保证一个类只有一个实例,并且提供一个访问它的全局访问点,该实例被所有模块共享。

1.3 单例模式的应用场景(来源)
1.3.1 作为唯一数据入口

假设一个对象负责更改本地设置,例如配置服务的网络端口号。如果出现两个或多个线程,每个线程拥有一个实例,线程并发共同进行配置。每个实例都在修改端口号。最终修改的结果就是不可控的。

1.3.2 共用的资源

现在我们假设有一个数据队列,由三个数据的生产者向队列push数据,一个消费者处理三个不同来源的数据。对队列进行pop操作。这就可能会涉及到四个线程并发的处理。怎样让这四个线程都能够获得到这个队列进行操作?这时候,使用单例模式。一个唯一的队列实例。不可以由其他对象创建,整个进程唯一,线程就能够通过这一唯一的实例进行数据的交互。

1.3.3 唯一的控制者

很多时候,我们需要对进程内的资源进行合理的调控,例如服务端进程在某一时刻,突然又大量数据或客户端请求进来。我们需要动态的增加数据处理线程,启用其他闲置的资源等等。这一时刻,决策者只能有一个。如果两个实例分别调控,最终的结果一定不是我们期望的。

2. 单例模式的实现

2.1 单例模式中Java与C++的类比

我们可以从网上迅速的找出Java的单例模式(懒汉和饿汉),如果对照着Java写出一个类似的C++的单例模式,会发现运行时会出错。因为Java有垃圾回收机制,而C++没有,所以C++在new一个实例后无法将实例delete,会发生内存泄露的问题。

class Singleton
{
public:
   static Singleton* getInstance()//静态方法,获取唯一实例
   {
       if(m_instance_ptr== NULL)//懒惰初始化,没有调用就不构建实例
       {
            m_instance_ptr = new Singleton; //创建实例
       }
       return m_instance_ptr;
   };
private:
 static  Singleton* m_instance_ptr;
  Singleton(){};//私有的构造方法
  ~Singleton(){};//私有的析构方法
}

2.2 C11中单例模式的最简单的实现
  • 使用静态局部变量作为实例返回,因为是静态实例,所以重复调用只会创建一个实例。并且静态变量的析构会在程序退出后自动进行。
    C11保证了静态局部变量的线程安全,当一个线程在初始化该局部变量的时候,其他线程会被挂起直到该线程初始化结束
  • 将赋值与复制函数都delete,因为不允许有多个实例。
class Singleton
{
public:
   static Singleton& getInstance()//静态方法,获取唯一实例
   {
        static Singleton instance;
        return instance;
   };
private:
  Singleton(){};//私有的构造方法
  ~Singleton(){};//私有的析构方法
   CSingleton(const CSingleton &)=delete;  
   CSingleton & operator = (const CSingleton &)=delete;  
}

你可能感兴趣的:(C++实现设计模式之单例模式)