分享一篇关于单例模式比较清晰的博文,并且使用了std::once_flag的方式:
https://www.cnblogs.com/xuhuajie/p/11647164.html
单例模式分为饿汉和懒汉两种方式,大部分项目里都用懒汉这种方式,就算饿汉方式天然的线程安全,不需要考虑内存释放,但由于是饿汉方式使用不使用都会在申请内存,所以大家都想办法来优化懒汉方式。
上面链接博文中总结的懒汉模式如下:
class SingletonUsePtr2
{
SINGLETON_CTOR(SingletonUsePtr2);
public:
static SingletonUsePtr2& Instance()
{
static std::once_flag s_flag;
std::call_once(s_flag, [&]() {
_ptr.reset(new SingletonUsePtr2);
});
return *_ptr;
}
private:
static std::unique_ptr<SingletonUsePtr2> _ptr;
};
1.使用智能指针,自动释放对象。
2.使用std::once_flag去掉老写法中的std::lock_guard<std::mutex>
堪称最简单的安全可靠的懒汉式实现了。。。。。。
再加上模板:
template<typename T>
class SingletonBase
{
SINGLETON_CTOR(SingletonBase);
public:
static T& Instance()
{
static T t; //饿汉式
return t;
}
};
template<typename T>
class SingletonBaseLazy
{
SINGLETON_CTOR(SingletonBaseLazy);
public:
static T& Instance()
{
static std::once_flag flag;
std::call_once(flag, [&](){_ptr.reset(new T); });
return *_ptr;
}
static std::unique_ptr<T> _ptr;
};
template<typename T>
std::unique_ptr<T> SingletonBaseLazy<T>::_ptr;
以下是百度apollo项目中写的单例样本,也基本采用了这种形式:
#define DISALLOW_COPY_AND_ASSIGN(classname) \
classname(const classname &) = delete; \
classname &operator=(const classname &) = delete;
#define DECLARE_SINGLETON(classname) \
public: \
static classname *Instance(bool create_if_needed = true) { \
static classname *instance = nullptr; \
if (!instance && create_if_needed) { \
static std::once_flag flag; \
std::call_once(flag, \
[&] { instance = new (std::nothrow) classname(); }); \
} \
return instance; \
} \
\
static void CleanUp() { \
auto instance = Instance(false); \
if (instance != nullptr) { \
CallShutdown(instance); \
} \
} \
\
private: \
classname(); \
DISALLOW_COPY_AND_ASSIGN(classname)