单例模式要注意两点:
- 通过一个Instance方法,得到类型唯一的实例
- 屏蔽掉外部创建类型实例的方法
有两种实现思路:
- 在Instance函数内部使用static声明变量,使其具有唯一实例
- 在cpp文件中定义全局static指针,并在Instance函数初始化一次
对于屏蔽外部的实现,只需将构造函数和析构函数声明成私有的即可(友元什么的特殊情况就不考虑了)。
思路1的代码比较简单,如下:
// somemgr.hpp
class SomeMgr {
public:
static SomeMgr& Instance();
int GetSomeValue() const { return some_value_; }
private:
SomeMgr() : some_value_(42) {}
~SomeMgr() { std::cout << "~SomeMgr()\n"; }
int some_value_;
};
// somemgr.cpp
#include "somemgr.hpp"
SomeMgr& SomeMgr::Instance()
{
static SomeMgr inst;
return inst;
}
思路2略为复杂,但由于是用指针维护单例,所以更加灵活,比如可以提供一个ReInit方法,来重新创建一个新的单例。
// somemgr.hpp
class SomeMgr {
public:
static SomeMgr* Instance();
bool ReInit(); // 重新创建单例对象, 并执行 Init
// user implements below
bool Init();
int GetSomeValue() const { return some_value_; }
private:
SomeMgr() : some_value_(0) {}
~SomeMgr() {}
int some_value_;
};
#include "somemgr.hpp"
static SomeMgr *some_mgr = nullptr;
SomeMgr* SomeMgr::Instance()
{
if (!some_mgr) {
some_mgr = new SomeMgr();
}
return some_mgr;
}
bool SomeMgr::ReInit()
{
SomeMgr *temp = new SomeMgr();
if (!temp->Init()) {
delete temp;
return false;
}
if (some_mgr)
delete some_mgr;
some_mgr = temp;
return true;
}
bool SomeMgr::Init()
{
some_value_ = 100;
return true;
}