设计模式学习-单例模式

单例模式:就是让一个对象始终只有一个,不能被拷贝。一般管理类我们会设计成单例。单例模式比较简单,但是还是需要注意一点,程序启动时应该初始化完单例对象。

实现示例

方式一:

class Singleton
{
public:
	static Singleton* Instance()
	{
		static Singleton instance;
		return &instance;
	}
private:
	Singleton() = default;
	~Singleton() = default;
	Singleton(const Singleton&) = delete;
	Singleton(Singleton&&) = delete;
	Singleton& operator==(const Singleton&) = delete;
};

方式二:

template<class T>
class Singleton
{
public:
	Singleton() = default;
	virtual ~Singleton() = default;
	static T* Instance()
	{
		static T t;
		return &t;
	}
private:
	Singleton(Singleton&&) = delete;
	Singleton(const Singleton&) = delete;
	Singleton& operator=(const Singleton&) = delete;
};

class mySingle : public Singleton<mySingle>
{
public:
private:
};

方式三:

class Singleton
{
public:
	static Singleton* Instance() { return &m_instance; }
private:
	static Singleton m_instance;
	Singleton() = default;
	~Singleton() = default;
	Singleton(const Singleton&) = delete;
	Singleton(Singleton&&) = delete;
	Singleton& operator==(const Singleton&) = delete;
};

Singleton Singleton::m_instance;

注意:

第一:单例对象应该在程序启动是就生成了,而不是在需要使用时生成,所以 懒汉式 方式不可取。

第二:单例对象在程序启动时就生成了,也就不存在多线程的问题,所以不需要写加锁的单例。及时单例生成时加锁也未必起作用,所以加锁避免多线程不可取。

 

利用智能指针 std::unique_ptr 方式实现唯一对象效果

#include <memory>
class MyClass
{
public:
private:
};
extern std::unique_ptr<MyClass> g_pMyClass;
std::unique_ptr<MyClass> g_pMyClass = nullptr;

g_pMyClass.reset(new MyClass);

单例管理器实现

#pragma once

#include <iostream>
#include <typeinfo>
#include <functional>
#include <exception>

using namespace std;

class Service
{
public:
	virtual const char* GetName()
	{
		return typeid(*this).name();
	}
};

template<class T>
class ServiceWrap
{
public:
	static_assert(std::is_base_of<Service, T>::value, "service class error");

	friend class ServiceManager;
	void new_service() { m_service = new T; }
	void free_service() { delete m_service; m_service = nullptr; }

	ServiceWrap(void) = default;
	~ServiceWrap() = default;
	ServiceWrap(const ServiceWrap&) = delete;
	ServiceWrap& operator=(const ServiceWrap&) = delete;
	ServiceWrap(const ServiceWrap&&) = delete;
	ServiceWrap& operator=(const ServiceWrap&&) = delete;
private:
	T* m_service;
};


class ServiceManager
{
public:
	template<class T>
	static ServiceWrap<T>* _reference()
	{
		static ServiceWrap<T> _obj;
		return &_obj;
	}
	template<class T>
	static T* GetService()
	{
		ServiceWrap<T>* res = _reference<T>();
		if (res != nullptr)
			return res->m_service;
		cout << "Service not found" << endl;
		return nullptr;
	}

	template<class T, typename... Args>
	struct _bind_function;

	template<typename T>
	struct _bind_function<T>
	{
		static void run(T* service) {}
	};

	template<class T, class F, typename...Args>
	struct _bind_function<T, F, Args...>
	{
		static decltype(auto) run(T* service, F&& f, Args&& ...args)
		{
			return std::bind(std::forward<F>(f), std::placeholders::_1, std::forward<Args>(args)...)(service);
		}
	};

	template<class T, typename... Args>
	static decltype(auto) Attach(Args&& ... args)
	{
		ServiceWrap<T>* res = _reference<T>();
		if (res->m_service)
		{
			throw "service attach duplicate...";
		}
		res->new_service();
		return _bind_function<T, Args...>::run(res->m_service, std::forward<Args>(args)...);
	}

	template<class T, typename... Args>
	static void Detach(Args&& ... args)
	{
		ServiceWrap<T>* res = _reference<T>();
		if (!res->m_service)
		{
			throw "service duplicate detach...";
		}
		_bind_function<T, Args...>::run(res->m_service, std::forward<Args>(args)...);
		res->free_service();
	}
};

实现测试:

#include "ServiceManager.hpp"


class PlayerService : public Service
{
public:
	~PlayerService()
	{
		//cout << "clear player..." << endl;
	}
	void init()
	{
		cout << "init player..." << endl;
	}

	void clear()
	{
		cout << "clear player..." << endl;
	}

	void print()
	{
		cout << "print player..." << endl;
	}
private:
};

template<class T>
static auto GetService = ServiceManager::GetService<T>;

int main()
{
	try
	{
		ServiceManager::Attach<PlayerService>(&PlayerService::init);
		auto service = GetService<PlayerService>();
		service->print();
		ServiceManager::Detach<PlayerService>(&PlayerService::clear);
	}
	catch (const char* what)
	{
		cout << what << endl;
	}

	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值