Design mode-creation mode-singleton mode

Singleton mode

Also known as: Single mode, Singleton

The singleton pattern is a creational design pattern that allows you to ensure that there is only one instance of a class and provide a global node to access that instance.

problem

The singleton mode solves two problems at the same time, so it violates the _single responsibility principle_:

1. Ensure that there is only one instance of a class .

2. Provide a global access node for the instance

solution

The realization of all singletons includes the following two identical steps:

  • The default constructor is private, to prevent other objects using a single class of embodiments newoperator.
  • Create a new static construction method as the constructor. This function will "secretly" call the private constructor to create the object and save it in a static member variable. All subsequent calls to this function will return this cache object.

If your code can access the singleton class, then it can call the static method of the singleton class. Whenever this method is called, it will always return the same object.

Singleton mode is suitable for application scenarios

If a certain class in the program has only one instance available to all clients, you can use the singleton mode.

Singleton mode prohibits the creation of objects of its own class by any means other than special construction methods. This method can create a new object, but if the object has already been created, it returns the existing object.

If you need to control global variables more strictly, you can use singleton mode.

The singleton mode is different from global variables in that it guarantees that there is only one instance of the class. Except for the singleton class itself, the cached instance cannot be replaced in any way.

Note that you can always adjust and set the limit number generation unit of the embodiment examples, only a modification 获取实例methods, i.e. getInstance code can be realized.

Method to realize

  1. Add a private static member variable to the class to save the singleton instance.
  2. Declare a public static construction method for obtaining singleton instances.
  3. Implement "delayed initialization" in a static method. This method creates a new object when it is first called and stores it in a static member variable. After that, the method will return this instance every time it is called.
  4. Make the constructor of the class private. Static methods of the class can still call the constructor, but other objects cannot call it.
  5. Check the client code and replace the call to the singleton's constructor with a call to its static construction method.

Example implementation-lazy man mode (locking judgment)

#include <iostream>
#include <mutex>
using namespace std;

class HttpServer 
{
    
    
public :
    static HttpServer *getInstance() 
    {
    
    
        if (instance == nullptr) 
        {
    
    
        /* 当第一个线程执行到此,对locker对象 "加锁",
           当第二个线程执行到此,如果检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁后再继续执行
           lock语句执行完也即代表上一个线程执行结束,同时对该对象"解锁"
           */
            std::unique_lock<std::mutex> lock(m_mutex);
            if (instance == nullptr) 
            {
    
    
                instance = new HttpServer();
            }
        }
        return instance;
    }
private:
    static HttpServer *instance;   定义一个用于保存静态变量的实例
    static std::mutex m_mutex;
    HttpServer() {
    
    }   //构造函数
    HttpServer(const HttpServer &) = delete;  //默认拷贝构造
    ~HttpServer() {
    
    }   //析构函数
};

HttpServer *HttpServer::instance = nullptr;
std::mutex HttpServer::m_mutex;

int main() 
{
    
    
    HttpServer *t1 = HttpServer::getInstance();
    HttpServer *t2 = HttpServer::getInstance();
    cout << t1 << " " << t2 << endl;
    return 0;
}

result

0x2216e70 0x2216e70   //相同的地址

Example implementation-hungry man mode (constructed during initialization)

#include <iostream>
#include <mutex>
using namespace std;

class HttpServer 
{
    
    
public :
    static HttpServer *getInstance() 
	{
    
     
        	return instance;
    }
private:
    static HttpServer *instance;   定义一个用于保存静态变量的实例
    static std::mutex m_mutex;
    HttpServer() {
    
    }   //构造函数
    HttpServer(const HttpServer &) = delete;  //默认拷贝构造
    ~HttpServer() {
    
    }   //析构函数
};

HttpServer *HttpServer::instance = new HttpServer();  
std::mutex HttpServer::m_mutex;

int main() 
{
    
    
    HttpServer *t1 = HttpServer::getInstance();
    HttpServer *t2 = HttpServer::getInstance();
    if (t1 == t2)
	{
    
    
       cout<<("Singleton works, both variables contain the same instance.")<< endl;
    }
    else
    {
    
    
       cout<<("Singleton failed, variables contain different instances.")<< endl;
     }
    return 0;
}

result

Singleton works, both variables contain the same instance.

Guess you like

Origin blog.csdn.net/qq_40513792/article/details/113526050