c++ singleton mode uses std::once_flag

Share a clear blog post about the singleton mode, and use the std::once_flag method:

https://www.cnblogs.com/xuhuajie/p/11647164.html

 

The singleton mode is divided into two modes: hungry man and lazy man. Most projects use the lazy man method. Even if the hungry man is naturally thread-safe, there is no need to consider memory release, but because it is the hungry man, it will be used or not used Apply for memory, so everyone thinks of ways to optimize the lazy way.

The lazy man mode summarized in the blog post linked above is as follows:

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. Use smart pointers to automatically release objects.

2. Use std::once_flag to remove std::lock_guard<std::mutex> in the old way of writing

The simplest safe and reliable lazy man style is realized. . . . . .

 

Plus the template:

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;

 

The following is a sample of the single case written in the Baidu apollo project, which basically adopts this form:

#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)

 

Guess you like

Origin blog.csdn.net/ynshi57/article/details/108083019