C++ 单例模式智能指针实现

在前端或者后台开发过程中,或多或少都要有一些全局变量,或者某个关键数据不允许重复构造,这个时候单例模式在C++程序中是一个不错的选择。
本代码示例结合智能指针做了一个单例模式。

class IwmGlobal : private std::enable_shared_from_this<IwmGlobal>
{
public:
	IwmGlobal(const IwmGlobal &) = delete;
	IwmGlobal &operator=(const IwmGlobal &) = delete;

	static std::shared_ptr<IwmGlobal> &instance() {
		if (nullptr != s_instance)
		{
			return s_instance;
		}

		Mutex::Locker lock(s_mutex);
		if (nullptr != s_instance)
		{
			return s_instance;
		}
		s_instance = shared_ptr<IwmGlobal>(new IwmGlobal());
		return s_instance;
	}
private:
	static std::shared_ptr<IwmGlobal>  s_instance;
	IwmGlobal() { m_bInit = FALSE; }
	static Mutex s_mutex;

private:
	BOOL m_bInit;

public:
	//所有配置文件相关信息
	std::shared_ptr<ConfigData>  appCfg;
	IchsPool<IWMBaseMsgPtr>      taskManMsgQueue;
	IchsPool<IWMBaseMsgPtr>      robotCtrlQueue;
	std::shared_ptr<crMioEx>     mqHandle;

	string listener_topic;
};
typedef std::shared_ptr<IwmGlobal> IwmGlobalPtr;

说明:
1、将构造函数声明为 private

 private:
	static std::shared_ptr<IwmGlobal>  s_instance;
	IwmGlobal() { m_bInit = FALSE; }

2、将C++类的默认实现的类重载函数去掉

    IwmGlobal(const IwmGlobal &) = delete;
	IwmGlobal &operator=(const IwmGlobal &) = delete;

3、初始化实例

static std::shared_ptr<IwmGlobal> &instance() {
		if (nullptr != s_instance)
		{
			return s_instance;
		}

		Mutex::Locker lock(s_mutex);
		if (nullptr != s_instance)
		{
			return s_instance;
		}
		s_instance = shared_ptr<IwmGlobal>(new IwmGlobal());
		return s_instance;
	}

因为单例模式无法直接调用make_shared()进行实例化,原因是构造函数为private,无法被外部调用,所以折中的方式是:

s_instance = shared_ptr<IwmGlobal>(new IwmGlobal());

注意:
因为是单例模式,相当于全局变量的存在,在程序加载过程中可能会存在instance多线程同时加载的情况, 为了避免该懒加载模式出现问题,最好加一个资源锁。
另外,单例模式设计过程需要明确区分,句柄初始化和数据加载初始化。
1、句柄初始化
句柄初始化为类或者结构体初始化,
2、数据加载初始化
而数据加载初始化是为了服务正常工作,需要加载配置数据或者连接初始化(如服务配置、tcp连接、服务初始化、db数据库连接初始化、MQ连接初始化、redis连接初始化)

个人理解,单例模式适合做句柄初始化,从程序架构上来看,最好将逻辑分开,一则污染了单例模式的设计本意,二则代码逻辑上对单例模式也是承重的负担。数据加载初始化建议采用工厂模式解耦处理。

你可能感兴趣的:(C/C++,c++,单例模式,开发语言)