Singleton mode of C++ design pattern (2)

Introduction

  Singleton Pattern (Singleton Pattern, also known as Singleton Pattern) is a widely used design pattern. Its purpose is to ensure that there is only one instance in a certain program of a class, and to provide a global access interface, that is, the instance is shared by the program.
  Class diagram of the singleton pattern:

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

  Features of singleton mode:

  1. Privateize its constructor to prevent the outside world from creating an instance of the class;
  2. Use the private static variable pointer of the class to point to the only instance of the class;
  3. Use a common static method to obtain an instance of the class.

Singleton mode implementation

1. Hungry Chinese

  What is Hungry Chinese Style? That is, under normal circumstances, the object has been instantiated when the program is initialized. No initialization is required for subsequent use.

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();

  The hungry-style singleton object is actually initialized before the main function of the program, so there is no thread safety issue.

2. Lazy man

  What is the lazy man? That is, under normal circumstances, when I need to use the object, I will initialize the object (that is, it will be initialized the first time it is used).

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. Thread safe way

  When using multi-threading, if you use a lazy way to implement a singleton, then there will be thread unsafe situations; suppose there are two threads, pthread_1 has just judged that intance is NULL as true, and when preparing to create an instance, Switched to pthread_2, at this time pthread_2 also judges that intance is NULL as true, creates an instance, and then continues to create an instance to return when switching back to pthread_1, then the requirements of the singleton mode are no longer met at this time. In this case, yes Because of the problem of multi-threaded access, then we will add a lock to synchronize the threads;

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. General editing method

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;

  This method uses some knowledge in C11, such as std::shared_ptr, std::once_flag, std::call_once; the advantage of this method is that when a program requires multiple singleton objects of different types , No need to implement the corresponding method, just inherit the class directly. As follows:

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

Use occasion

  1. The system only needs one instance object, or considering that the resource consumption is too large, only one object is allowed to be created;
  2. A single instance of the client calling class is only allowed to use one public access point, and it is not allowed to access the instance by other means (that is, a common static method) except this access point.

Guess you like

Origin blog.csdn.net/CFH1021/article/details/108906561