c++ std:call_once 与 单例模式实现

知识点

c++ std:call_once 可以用于保证某个函数在多线程环境下只被调用一次。

std::enable_if 泛型编程中模板最优匹配原则,template<bool Cond, class T = void> struct enable_if {}; //The type T is enabled as member type enable_if::type if Cond is true.
std::decltype 表达式类型推导,该推导过程在编译期完成,并不会真正对表达式求值。
constexpr 声明时带有constexpr关键字的变量是常量表达式,因而可以被用做编译期计算。
如果带有constexpr的函数的参数被编译器检测到为编译期常量,那么这个函数就可以自动地在编译期运行。
 
c++ 技巧,如何判断某个class 是否有某个成员函数 Shutdown
 
template <typename T>                                   
struct HasShutdown {                                           
template <typename Class>                             
static constexpr bool Test(decltype(&Class::Shutdown)*) { 
  return true;                                        
}                                                     
template <typename>                                   
static constexpr bool Test(...) {                     
  return false;                                       
}                                                     
                                                      
static constexpr bool value = Test<T>(nullptr);       
};                                                      
                                                      
template <typename T>                                   
constexpr bool HasShutdown<T>::value;

template <typename T>
typename std::enable_if<HasShutdown<T>::value>::type CallShutdown(T *instance) {
  instance->Shutdown();
}

template <typename T>
typename std::enable_if<!HasShutdown<T>::value>::type CallShutdown(T *instance) {
  (void)instance;
}

class Singleton
{
public:
    static Singleton* Instance(bool create_if_needed = true) {
        static Singleton *instance = nullptr;
        if (!instance && create_if_needed) { 
            static std::once_flag flag;
            std::call_once(flag,
                [&] { instance = new (std::nothrow) Singleton(); });
        }
        return instance;
    }
    static void CleanUp() {
        auto instance = Instance(false);
        if (instance != nullptr) {
            //delete instance;
            CallShutdown(instance); 
        }
    }     
private:
    Singleton();
    ~Singleton();
};

 

posted @ 2021-01-21 11:45  Ray.floyd  阅读(688)  评论(0编辑  收藏  举报