El modo singleton de c ++ usa std :: once_flag

Comparta una publicación de blog clara sobre el modo singleton y use el método std :: once_flag:

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

 

El modo singleton se divide en dos modos: hombre hambriento y hombre perezoso. La mayoría de los proyectos utilizan el método del hombre perezoso. Incluso si el hombre hambriento es naturalmente seguro para subprocesos, no hay necesidad de considerar la liberación de memoria, sino porque es el hombre hambriento , se usará o no. Solicite memoria, para que todos piensen en formas de optimizar la forma perezosa.

El modo de hombre perezoso resumido en la publicación del blog vinculada anteriormente es el siguiente:

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. Utilice punteros inteligentes para liberar objetos automáticamente.

2. Utilice std :: once_flag para eliminar std :: lock_guard <std :: mutex> en la forma antigua de escribir

Se realiza el estilo de hombre vago más simple, seguro y confiable. . . . . .

 

Más la plantilla:

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;

 

El siguiente es un ejemplo del caso único escrito en el proyecto apollo de Baidu, que básicamente adopta esta forma:

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

 

Supongo que te gusta

Origin blog.csdn.net/ynshi57/article/details/108083019
Recomendado
Clasificación