• 设计模式-单例模式


    单例模式Singleton):

        保证一个类仅有一个实例,并提供一个访问它的全局访问点。


        通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。一个最好的颁发就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且提供一个访问该实例的方法(比如我们给一个项目写一个日志系统)。
        单例模式分为懒汉模式和饿汉模式,以及在创建实例的时候要考虑多线程问题,也就是需要上锁,上锁可以采用一般的锁,也可以采用双重锁的方式减少上锁时内核态与用户态切换导致的资源浪费,同时因为饿汉模式的特性,饿汉模式不涉及到多线程上锁问题。
    接下来实现一下懒汉模式和饿汉模式,先不考虑多线程问题,最后在单独说下多线程问题的处理代码。
    单例模式(懒汉)

    .h

    #pragma once
    
    #include <iostream>
    using namespace std;
    
    class CWork
    {
    private:
    	static CWork * m_cWork;
    	static int m_nMarkRunCount;
    	CWork(){} //By using the constructor as a private block to prevent users from using the class variable.
    	void DoWrite()
    	{
    		cout<<"WorkCount:"<<m_nMarkRunCount++<<endl;
    	}
    public:
    	static void GetInstance()
    	{//Create a static function of the entity
    		if(m_cWork == NULL)
    		{
    			m_cWork = new CWork();
    		}
    	}
    	static void WriteLog() 
    	{//work function
    		if(m_cWork == NULL)
    		{
    			cout<<"no instance"<<endl;
    			return ;
    		}
    		m_cWork->DoWrite();
    	}
    };
    
    .cpp

    #include "stdafx.h"
    #include "SingletonMode.h"
    
    CWork * CWork::m_cWork = NULL;
    int CWork::m_nMarkRunCount = 0;
    客户端调用:

    #include "stdafx.h"
    #include "SingletonMode.h"
    #include <iostream>
    #include <string>
    using namespace std;
    
    int main()
    {
    	CWork::WriteLog();
    	CWork::GetInstance();
    	CWork::WriteLog();
    	CWork::WriteLog();
    	return 0;
    }
    运行结果:

    单例模式(饿汉)

    .h

    #pragma once
    
    #include <iostream>
    using namespace std;
    
    class CWork
    {
    private:
    	static CWork * m_cWork;
    	static int m_nMarkRunCount;
    	CWork(){} //By using the constructor as a private block to prevent users from using the class variable.
    	void DoWrite()
    	{
    		cout<<"WorkCount:"<<m_nMarkRunCount++<<endl;
    	}
    public:
    	static CWork* GetInstance()
    	{//Create a static function of the entity
    		if(m_cWork == NULL)
    		{
    			m_cWork = new CWork();
    		}
    		return m_cWork;
    	}
    	static void WriteLog() 
    	{//work function
    		if(m_cWork == NULL)
    		{
    			cout<<"no instance"<<endl;
    			return ;
    		}
    		m_cWork->DoWrite();
    	}
    };
    
    .cpp

    #include "stdafx.h"
    #include "SingletonMode.h"
    
    CWork * CWork::m_cWork = CWork::GetInstance();
    int CWork::m_nMarkRunCount = 0;
    客户端调用:

    #include "stdafx.h"
    #include "SingletonMode.h"
    #include <iostream>
    #include <string>
    using namespace std;
    
    int main()
    {
    	CWork::WriteLog();
    	CWork::WriteLog();
    	CWork::WriteLog();
    	return 0;
    }
    运行结果:


    双重锁:
    Static void GetInstance()
    {
    If(m_cWork == NULL)
    {
        Lock
        {
             If(m_cWork == NULL)
             {
                  m_cWork = new CWork();
             }
        } 
    }
    }//注意第二个if的作用。


  • 相关阅读:
    Tomcat 之 Aio的安装步骤
    redis的安装问题
    Tomcat开机自启
    常用基本SQL语句
    点击开启此虚拟机时,出现“该虚拟机似乎正在使用中”问题
    sql表连接left join,right join,inner join三者之间的区别
    Lua 中 ipairs 与 pairs 的区别
    Lua 栈【转】【学习笔记】
    Nodejs 环境设置
    nodejs取得当前执行路径
  • 原文地址:https://www.cnblogs.com/csnd/p/12062331.html
Copyright © 2020-2023  润新知