Modo singleton del patrón de diseño C ++ (2)

Introducción

  Singleton Pattern (Singleton Pattern, también conocido como Singleton Pattern) es un patrón de diseño muy utilizado. Su propósito es garantizar que solo haya una instancia en un determinado programa de una clase y proporcionar una interfaz de acceso global, es decir, la instancia es compartida por el programa.
  Diagrama de clases del patrón singleton:

Singleton -$Singleton *unique_instance$ -Singleton() +$Singleton* getInstance()

  Características del modo singleton:

  1. Privatizar su constructor para evitar que el mundo exterior cree una instancia de la clase;
  2. Usar el puntero de variable estática privada de la clase para apuntar a la única instancia de la clase;
  3. Usar un método estático común para obtener una instancia de la clase.

Implementación del modo singleton

1. Chino hambriento

  ¿Qué es el estilo chino hambriento? Es decir, en circunstancias normales, cuando se inicializa el programa, se ha creado una instancia del objeto. No se requiere inicialización para su uso posterior.

class Singleton
{
private:
	static Singleton* instance;
private:
	Singleton() {};
	~Singleton() {};
	Singleton(const Singleton&);
	Singleton& operator=(const Singleton&);
public:
	static Singleton* getInstance() 
    {
		return instance;
	}
};

//initialize defaultly
Singleton* Singleton::instance = new Singleton();

  El objeto singleton de estilo hambriento en realidad se inicializa antes de la función principal del programa, por lo que no hay problemas de seguridad de subprocesos.

2. Hombre vago

  ¿Qué es el holgazán? Es decir, en circunstancias normales, cuando necesite utilizar el objeto, inicializaré el objeto (es decir, se inicializará la primera vez que se utilice).

class Singleton
{
private:
	static Singleton* instance;
private:
	Singleton() {};
	~Singleton() {};
	Singleton(const Singleton&);
	Singleton& operator=(const Singleton&);
public:
	static Singleton* getInstance() 
    {
		if(instance == NULL) 
			instance = new Singleton();
		return instance;
	}
};

// init static member
Singleton* Singleton::instance = NULL;

3. Manera segura de subprocesos

  Al usar subprocesos múltiples, si usa una forma perezosa para implementar un singleton, entonces habrá situaciones inseguras de subprocesos; supongamos que hay dos subprocesos, pthread_1 acaba de juzgar que intance es NULL como verdadero, y cuando se prepara para crear una instancia, Cambiado a pthread_2, en este momento pthread_2 también juzga que intance es NULL como verdadero, crea una instancia y luego continúa creando una instancia cuando se vuelve a cambiar a pthread_1 para regresar, entonces los requisitos del modo singleton ya no se cumplen en este momento, en este caso, sí Debido al problema del acceso multiproceso, agregaremos un candado para sincronizar los subprocesos;

class Singleton
{
private:
	static Singleton* instance;	
	static pthread_mutex_t mutex;
private:
	Singleton() {};
	~Singleton() {};
	Singleton(const Singleton&);
	Singleton& operator=(const Singleton&);
public:
	static Singleton* getInstance() 
    {
    	if (NULL == instance ){
            pthread_mutex_lock(&mutex)
		    if(instance == NULL) 
			    instance = new Singleton();
            pthread_mutex_unlock(&mutex)
        }
		return instance;
	}
};


pthread_mutex_t singleton::mutex;
// init static member
Singleton* Singleton::instance = NULL;

4. Método de edición general

template <typename T>
class Singleton {

public:
    static T* GetInstance(){
        static std::once_flag s_flag;
        std::call_once(s_flag, [&](){
            singleton_ptr.reset(new T);
        });

        return singleton_ptr.get();
    }

protected:
    Singleton(){};
    ~Singleton(){};

private:
    static std::shared_ptr<T> singleton_ptr;

    Singleton(const Singleton&) = delete;
    Singleton&operator=(const Singleton&) = delete;
}; // end singleton

template<typename T> std::shared_ptr<T> Singleton<T>::singleton_ptr;

  Este método usa algunos conocimientos en C11, como std :: shared_ptr, std :: once_flag, std :: call_once; la ventaja de este método es que cuando un programa requiere múltiples objetos singleton de diferentes tipos , No es necesario implementar el método correspondiente, solo hereda la clase directamente. Como sigue:

class TestClass: public Singleton<TestClass> {
    public:
        TestClass();
        ~TestClass();
    };

Use ocasión

  1. El sistema solo necesita un objeto de instancia, o considerando que el consumo de recursos es demasiado grande, solo se permite crear un objeto;
  2. Una sola instancia de la clase de llamada del cliente solo puede usar un punto de acceso público, y el acceso a la instancia por otros medios (es decir, un método estático común) no está permitido excepto este punto de acceso.

Supongo que te gusta

Origin blog.csdn.net/CFH1021/article/details/108906561
Recomendado
Clasificación