C++线程安全的单例模式(返回指针,引用,模板,饿汉式,饱汉式)

一、返回指针,饱汉式:

singleton.h

#ifndef __CC_SINGLETON_H__
#define __CC_SINGLETON_H__
#include <iostream>
#include <mutex>
using std::cout;
using std::endl;
namespace cc
{
	class Singleton
	{
		public:
			static Singleton * getInstance();
			static void destroyInstance();
		private:
			Singleton(){cout << "Singleton()" << endl;}
			~Singleton(){cout << "~Singleton()" << endl;}
			//禁止复制
			Singleton(const Singleton &) = delete;
			Singleton & operator=(const Singleton &) = delete;
		private:
			static std::mutex m_mutex;
			static Singleton * m_pInstance;
	};

	Singleton* Singleton::m_pInstance = nullptr;
	std::mutex Singleton::m_mutex;

	Singleton* Singleton::getInstance(){
		if(nullptr == m_pInstance){
			std::lock_guard<std::mutex> guard(m_mutex);
			if(nullptr == m_pInstance){
				m_pInstance = new Singleton();
			}
		}
		return m_pInstance;
	}

	void Singleton::destroyInstance(){
		if(m_pInstance != nullptr){
			delete m_pInstance;
			m_pInstance = nullptr;
		}
	}
}//end of namespace
#endif

test.cc

#include "singleton.h"
#include "stdio.h"
#include <iostream>
using std::cout;
using std::endl;
using namespace cc;
int main(){
	cout << "......begin......" << endl;
	Singleton *p1 = Singleton::getInstance();
	Singleton *p2 = Singleton::getInstance();
	Singleton *p3 = Singleton::getInstance();
	printf("p1 = %p\n",p1);
	printf("p2 = %p\n",p2);
	printf("p3 = %p\n",p3);
	Singleton::destroyInstance();
	Singleton::destroyInstance();
	Singleton::destroyInstance();
	cout << "......end......" << endl;
}

运行结果:

......begin......
Singleton()
p1 = 0x22c8030
p2 = 0x22c8030
p3 = 0x22c8030
~Singleton()
......end......
 

二、返回引用,饿汉式:

#ifndef __CC_SINGLETON_H__
#define __CC_SINGLETON_H__
#include <iostream>
using std::cout;
using std::endl;
namespace cc
{
	class Singleton
	{
		public:
			static Singleton & getInstance();
		private:
			Singleton(){cout << "Singleton()" << endl;}
			~Singleton(){cout << "~Singleton()" << endl;}
			Singleton(const Singleton &) = delete;
			Singleton & operator=(const Singleton &) = delete;
		private:
			static Singleton m_Instance;
	};

	Singleton Singleton::m_Instance;

	Singleton & Singleton::getInstance(){
		return m_Instance;
	}

}//end of namespace
#endif

 

三、返回引用,饱汉式:

返回的是静态局部变量,由于静态局部变量是非线程安全的,所以加锁和标志位

#ifndef __CC_SINGLETON_H__
#define __CC_SINGLETON_H__
#include <iostream>
#include <mutex>
using std::cout;
using std::endl;

namespace cc
{
	class Singleton
	{
		public:
			static Singleton & getInstance();
		private:
			static Singleton & createInstance();
		private:
			Singleton(){cout << "Singleton()" << endl;}
			~Singleton(){cout << "~Singleton()" << endl;}
			Singleton(const Singleton &) = delete;
			Singleton & operator=(const Singleton &) = delete;
		private:
			//由于局部静态变量是非线程安全的,所以要加锁,并加一个标志位
			static bool m_isExisted;//标记实例是否存在
			static std::mutex m_mutex;
	};

	bool Singleton::m_isExisted = false;
	std::mutex Singleton::m_mutex;

	Singleton & Singleton::getInstance(){
		if(false == m_isExisted){
			std::lock_guard<std::mutex> guard(m_mutex);
			if(false == m_isExisted){
				return createInstance();
			}
		}
		return createInstance();
	}

	Singleton & Singleton::createInstance(){
		static Singleton instance;
		return instance;
	}

}//end of namespace
#endif

三、模板实现:

singleton.h

#ifndef __CC_SINGLETON_H__
#define __CC_SINGLETON_H__
#include <iostream>
#include <mutex>
using std::cout;
using std::endl;
namespace cc
{
	template<typename T>
	class Singleton
	{
		public:
			static T * getInstance();
			static void destroyInstance();
		private:
			Singleton(){cout << "Singleton()" << endl;}
			~Singleton(){cout << "~Singleton()" << endl;}
			Singleton(const Singleton &) = delete;
			Singleton & operator=(const Singleton &) = delete;
		private:
			static std::mutex m_mutex;
			static T * m_pInstance;
	};

	template<typename T>
	T* Singleton<T>::m_pInstance = nullptr;

	template<typename T>
	std::mutex Singleton<T>::m_mutex;

	template<typename T>
	T* Singleton<T>::getInstance(){
		if(nullptr == m_pInstance){
			std::lock_guard<std::mutex> guard(m_mutex);
			if(nullptr == m_pInstance){
				m_pInstance = new T;
			}
		}
		return m_pInstance;
	}

	template<typename T>
	void Singleton<T>::destroyInstance(){
		if(m_pInstance != nullptr){
			delete m_pInstance;
			m_pInstance = nullptr;
		}
	}
}//end of namespace
#endif

test.cc

#include "singleton.h"
#include "stdio.h"
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
using namespace cc;
int main(){
	cout << "......begin......" << endl;
	int *pint1 = Singleton<int>::getInstance();
	int *pint2 = Singleton<int>::getInstance();
	int *pint3 = Singleton<int>::getInstance();
	float *pfloat1 = Singleton<float>::getInstance();
	float *pfloat2 = Singleton<float>::getInstance();
	float *pfloat3  = Singleton<float>::getInstance();
	string *pstr1  = Singleton<string>::getInstance();
	string *pstr2  = Singleton<string>::getInstance();
	string *pstr3  = Singleton<string>::getInstance();
	printf("pint1 = %p\n",pint1);
	printf("pint2 = %p\n",pint2);
	printf("pint3 = %p\n",pint3);
	printf("pfloat1 = %p\n",pfloat1);
	printf("pfloat2 = %p\n",pfloat2);
	printf("pfloat3 = %p\n",pfloat3);
	printf("pstr1 = %p\n",pstr1);
	printf("pstr2 = %p\n",pstr2);
	printf("pstr3 = %p\n",pstr3);
	Singleton<int>::destroyInstance();
	Singleton<int>::destroyInstance();
	Singleton<int>::destroyInstance();
	Singleton<float>::destroyInstance();
	Singleton<float>::destroyInstance();
	Singleton<float>::destroyInstance();
	Singleton<double>::destroyInstance();
	Singleton<double>::destroyInstance();
	Singleton<double>::destroyInstance();
	Singleton<string>::destroyInstance();
	Singleton<string>::destroyInstance();
	Singleton<string>::destroyInstance();
	cout << "......end......" << endl;
}

运行结果:

......begin......
pint1 = 0x1b81030
pint2 = 0x1b81030
pint3 = 0x1b81030
pfloat1 = 0x1b81050
pfloat2 = 0x1b81050
pfloat3 = 0x1b81050
pstr1 = 0x1b81070
pstr2 = 0x1b81070
pstr3 = 0x1b81070
......end......
 

四、单例模式自动释放:

#ifndef __CC_SINGLETON_H__
#define __CC_SINGLETON_H__
#include <iostream>
#include <mutex>
using std::cout;
using std::endl;
namespace cc
{
	class Singleton
	{
		//嵌套类,自动释放内存
		public:
			static Singleton * getInstance();
			static void destroyInstance();
		private:
			Singleton(){cout << "Singleton()" << endl;}
			~Singleton(){cout << "~Singleton()" << endl;}
			Singleton(const Singleton &) = delete;
			Singleton & operator=(const Singleton &) = delete;
		private:
			class Auto;
			static Auto _auto;//自动释放类
			static std::mutex _mutex;
			static Singleton * _pInstance;
	};

	class Singleton::Auto{
		public:
			~Auto(){ destroyInstance(); }
	};

	Singleton::Auto Singleton::_auto;
	Singleton* Singleton::_pInstance = nullptr;
	std::mutex Singleton::_mutex;

	Singleton* Singleton::getInstance(){
		if(nullptr == _pInstance){
			std::lock_guard<std::mutex> guard(_mutex);
			if(nullptr == _pInstance){
				_pInstance = new Singleton();
			}
		}
		return _pInstance;
	}

	void Singleton::destroyInstance(){
		if(_pInstance != nullptr){
			delete _pInstance;
			_pInstance = nullptr;
		}
	}
}//end of namespace
#endif

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值