Definition: SingletonPattern ensures that a class has only one instance and provides a global access point to it.
In fact, only one door can be entered, and only one person can be entered at a time. This is just like an example from a previous bo. Many people wait in queue to go to the restroom to squat. Each time, only one person can go to the sleep. The reason for implementing the Singleton mode is either resource sharing or resource control. The so-called resource sharing is because the Singleton mode ensures that only one instance is available for a class, so the instances accessed by everyone are consistent. Resource Control mainly reduces resource application and release.
Type: creation mode
Class diagram:
Overview:
Global variables are often used in many large programs. If you do not need global variables, you need to input global variables with parameters in the used modules. This is very troublesome. To reduce the use of global variables, use them if necessary. The Singleton mode is an improvement to the traditional global model. A single instance can be instantiated with latency, that is, it can be instantiated only when needed. For some large classes, delayed instantiation is advantageous.
Note that in C # and Java, there are hunger Singleton mode (initialized when the variable is declared) and lazy mode (initialized when needed ). In the GoF book, only the lazy mode is mentioned, because the static variables of C ++ are uncertain during initialization. The initialization sequence of static variables in the same class is the same as that of the declaration, but the initialization sequence of static variables in different classes is uncertain.
In addition, in multithreading, you need to pay attention to the access critical section and add Lock to control it.
Code: added a static object to process memory garbage collection.
The code is as follows: |
Copy code |
// C ++ Class CSingleton { // Private constructor. Objects cannot be constructed directly. Private: CSingleton () { } Public: Static CSingleton * GetInstance () { If (NULL = m_pSingleton) M_pSingleton = new CSingleton (); Return m_pSingleton; } Void SetIdx (int _ nIdx) { M_nIdx = _ nIdx; } Int GetIdx () { Return m_nIdx; } Private: Int m_nIdx; Static CSingleton * m_pSingleton; Public: Class CRecycle { Public: ~ CRecycle () { If (NULL! = CSingleton: m_pSingleton) { DeleteCSingleton: m_pSingleton; } } }; Static CRecycle m_recycle; }; // Initialize static member variables CSingleton * CSingleton: m_pSingleton = NULL; CSingleton: CRecycleCSingleton: m_recycle; Int _ tmain (int argc, _ TCHAR * argv []) { CSingleton: GetInstance ()-> SetIdx (1 ); Return0; } |
First: Simple implementation (inert instantiation)
The code is as follows: |
Copy code |
Namespace Singleton { Public class Program { Static void Main (string [] args) { Singleton s1 = Singleton. Instance; Singleton s2 = Singleton. Instance; If (s1 = s2) { Console. WriteLine ("Objects are the same instance "); } Console. Read (); } } Public sealed class Singleton { Private Singleton (){} Private static Singleton instance = null; Public static Singleton Instance { Get { If (instance = null) { Instance = new Singleton (); } Return instance; } } } } |
Simple implementation is not secure for threads, because multiple Singleton instances may be generated in the case of multithreading. Multiple Singleton instances are generated if multiple threads are judged (instance = null) and no instances are created. For simple implementation, Singleton instantiation is not created when an application is started, so we call it "inert instantiation", which can avoid unnecessary instance instantiation during application startup.
Type 2: secure threads
The code is as follows: |
Copy code |
Namespace Singleton { Public class Program { Static void Main (string [] args) { Singleton s1 = Singleton. Instance; Singleton s2 = Singleton. Instance; If (s1 = s2) { Console. WriteLine ("Objects are the same instance "); } Console. Read (); } } Public sealed class Singleton { Private Singleton (){} Private static Singleton instance = null; Private static readonly object padLock = new object (); Public static Singleton Instance { Get { Lock (padLock) { If (instance = null) { Instance = new Singleton (); } Return instance; } } } } } |
Secure threads. This is a supplement to simple instances. Because the lock () operation is provided, this ensures that only one thread enters. However, locking requires additional overhead and performance loss.