单例模式:就是让一个对象始终只有一个,不能被拷贝。一般管理类我们会设计成单例。单例模式比较简单,但是还是需要注意一点,程序启动时应该初始化完单例对象。
实现示例
方式一:
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;
}