C++单例模式

    C++中的单例模式一般分两种,一是饿汉单例模式,二是懒汉单例模式。其中懒汉单例模式本身保证线程安全,而饿汉单例模式需要加锁才能保证线程安全。并且,饿汉单例模式加锁后可以通过判断两次来提高性能,从而演化成双检测单例模式。下面用代码表达:

一、饿汉单例模式

Singleton_Eager.h

#pragma once

namespace Singleton_Eager
{
	// 饿汉单例模式(保证线程安全)
	class Singleton
	{
	private:
		Singleton(void);
		~Singleton(void);

	public:
		static Singleton* GetInstance();

	private:
		Singleton& operator=(const Singleton&);

		static Singleton*		m_Instance;
	};
}


Singleton_Eager.cpp

#include "StdAfx.h"
#include "Singleton_Eager.h"

using namespace Singleton_Eager;

Singleton* Singleton::m_Instance = new Singleton();

Singleton::Singleton(void)
{
}

Singleton::~Singleton(void)
{
}

Singleton* Singleton_Eager::Singleton::GetInstance()
{
	return m_Instance;
}

二、懒汉单例模式

Singleton_Lazy.h

#pragma once

namespace Singleton_Laze
{
	// 懒汉单例模式(不保证线程安全,可以加锁)
	class Singleton
	{
	private:
		Singleton(void);
		~Singleton(void);

	public:
		static Singleton* GetInstance();

	private:
		Singleton& operator=(const Singleton&);  

		static Singleton*		m_Instance;  
	};
}


Singleton_Lazy.cpp

#include "StdAfx.h"
#include "Singleton_Lazy.h"

using namespace Singleton_Laze;


Singleton*		Singleton::m_Instance = NULL;


Singleton::Singleton(void)
{
}

Singleton::~Singleton(void)
{
	if (m_Instance != NULL)
	{
		delete m_Instance;
		m_Instance = NULL;
	}
}

Singleton* Singleton::GetInstance()
{
	if (m_Instance == NULL)
	{
		m_Instance = new Singleton();
	}

	return m_Instance;
}

三、双检测单例模式

Singleton_Double.h

#pragma once
#include <Windows.h>

namespace Singleton_Doule
{
	// 双检测单例模式,由饿汉单例模式演化而来
	class Singleton
	{
	private:
		Singleton(void);
		~Singleton(void);

	public:
		static Singleton* GetInstance();

	private:
		Singleton& operator=(const Singleton&);

		static Singleton*			m_Instance;
		static CRITICAL_SECTION 	m_cs;
	};
}




Singleton_Double.cpp

#include "StdAfx.h"
#include "Singleton_Double.h"

using namespace Singleton_Doule;

Singleton*			Singleton::m_Instance = NULL;  
CRITICAL_SECTION	Singleton::m_cs;

Singleton::Singleton(void)
{
}

Singleton::~Singleton(void)
{
}

Singleton* Singleton::GetInstance()
{
	// 双检测保证
	if (m_Instance == NULL)
	{
		InitializeCriticalSection(&m_cs);
		EnterCriticalSection(&m_cs);		//进入临界区
		
		if (m_Instance == NULL)
		{
			m_Instance = new Singleton();
		}

		LeaveCriticalSection(&m_cs);		//离开临界区
		DeleteCriticalSection(&m_cs);
	}

	return m_Instance;
}

四、测试代码

SingletonTest.cpp

#include "StdAfx.h"
#include "Singleton_Double.h"

using namespace Singleton_Doule;

Singleton*			Singleton::m_Instance = NULL;  
CRITICAL_SECTION	Singleton::m_cs;

Singleton::Singleton(void)
{
}

Singleton::~Singleton(void)
{
}

Singleton* Singleton::GetInstance()
{
	// 双检测保证
	if (m_Instance == NULL)
	{
		InitializeCriticalSection(&m_cs);
		EnterCriticalSection(&m_cs);		//进入临界区
		
		if (m_Instance == NULL)
		{
			m_Instance = new Singleton();
		}

		LeaveCriticalSection(&m_cs);		//离开临界区
		DeleteCriticalSection(&m_cs);
	}

	return m_Instance;
}

五、后续

    另外送你一个牛逼的用模板实现的单例模式:

Singleton.hpp

//
// Singleton模板
// 参考 boost 1-36-0/pool/detail/singleton.hpp
// 说明 http://www.yulefox.com/index.php/20081119/design-patterns-03.html/
//

#ifndef _SINGLETON_H_
#define _SINGLETON_H_

template <typename T> 
struct singleton_default
{ 
public: 
    typedef T object_type; 
    static object_type& instance() 
    { 
        static object_type obj; 
        create_object.do_nothing();
        return obj; 
    } 

private: 
    struct object_creator 
    { 
        object_creator() { singleton_default<T>::instance(); }
        inline void do_nothing() const {} 
    }; 
    static object_creator create_object; 
    singleton_default(); 
}; 

template <typename T> 
typename singleton_default<T>::object_creator 
singleton_default<T>::create_object;

#define INSTANCE(class_name) singleton_default<class_name>::instance()

#endif // _SINGLETON_H_

使用示例:

INSTANCE(类名).方法();

六、参考文献

https://blog.csdn.net/woxiaohahaa/article/details/51344409

七、源码链接

https://download.csdn.net/download/shaoyiju/10336093

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值