Design Mode-singleton Mode
The Singleton model may be a design model that we usually have to deal with. Many of our friends will be asked during enterprise interviews. Speaking of this, I think of the ugly speech I had made during my graduation interview. My heart would always feel a little embarrassed and it was really bad to hate my own base. Okay. Let's go back to the topic. What is the singleton mode?
Concept:
Singleton ensures that a class has only one instance and provides a global access point to it.
In C ++, you can use a global variable to achieve this, but such code has defects, especially in multithreaded programs. You can use a global object to easily access the instance, but you cannot declare only one object. That is to say, you can still create local instances of the same class except for one global instance.
Class Diagram:
Function:
1. control resource usage and control concurrent resource access through thread synchronization;
2. Control the number of instances generated to save resources;
3. It is used as a communication media, that is, data sharing. It allows communication between multiple unrelated two threads or processes without establishing a direct association.
Application scenarios:
1. System log output. Because log files are all shared and open, it is recommended that you use an instance to perform operations and do not turn them off cyclically;
2. Windows Recycle Bin (Recycle Bin );
3. One MODEM connection and only one telephone line are required;
4. In Windows Task Manager, you cannot open more than two Task managers;
5. Connect a PC to a keyboard.
Code:
Class CSingleton {// other members public: static CSingleton * GetInstance () {if (m_pInstance = NULL) // determine whether to call m_pInstance = new CSingleton (); return m_pInstance ;} private: CSingleton () {}; static CSingleton * m_pInstance ;};
The code shows the features of the singleton mode:
1. constructor is private, so that such instances cannot be created elsewhere;
2. There is a static pointer m_pInstance pointing to a unique instance, and the type is private;
3. It has a public GetInstance function that can obtain this unique instance and only creates this instance (lazy initialization) when it is called for the first time, all GetInstance functions return pointers of the same instance. (Note: To return the static instance pointer m_pInstance, The GetInstance return value must also be declared as static .)
Test code:
Static void main () {CSingleton * s1 = CSingleton. getInstance (); CSingleton * s2 = CSingleton. getInstance (); if (s1 = s2) {Cout <"two objects are the same instance!" <
Result: "The two objects are the same instance !".
Code Analysis:
1. When will the space pointed to by m_pInstance be released?
You can call GetInstance () at the end of the program and delete the returned pointer. In this way, the function can be implemented, but it is prone to errors. Because such additional code is easy to forget, and it is difficult to ensure that after the delete operation, no code can call the GetInstance function. A proper method is to let the class know how to delete itself, or to put the delete operation on a proper point in the operating system, make it automatically executed when appropriate. We know that at the end of the program, the system will automatically analyze all global variables. In fact, the system will analyze the static member variables of all classes, just like these static members are also global variables. With this feature, we can define such a static member variable in the singleton class, and its only job is to delete the singleton class instance in the destructor. The Code is as follows:
Class CSingleton {// other members public: static CSingleton * GetInstance () {if (m_pInstance = NULL) // determine whether to call m_pInstance = new CSingleton (); return m_pInstance ;} private: CSingleton () {}; static CSingleton * m_pInstance; class CGarbo // its unique job is to delete the CSingleton instance {public :~ In the destructor :~ CGarbo () {if (CSingleton: m_pInstance) delete CSingleton: m_pInstance ;}// defines a static member. When the program ends, the system automatically calls its destructor Static CGabor Garbo ;};
Class CGarbo is defined as a private embedded class of CSingleton (the default value is private) to prevent this class from being abused elsewhere.
The program defines a static member Garbo of CGabor. When the program runs, the system automatically calls the destructor of the static member Garbo of CSingleton, which deletes the unique instance of the single instance.
Since then, we no longer have to worry about the release of objects, nor do any operations on the release of objects.
2. How should I pay attention to the singleton mode under multiple threads?
The preceding Singleton mode is not thread-safe, so we need to rewrite the preceding Singleton mode with the multi-thread synchronization method and double lock. The Code is as follows:
// Thread synchronization class LockSingleton {public: inline LockSingleton () {m_hMutex = CreateMutex (NULL, FALSE, NULL);} inline ~ LockSingleton () {CloseHandle (m_hMutex);} inline void Lock () {WaitForSingleObject (m_hMutex, INFINITE);} inline void Unllock () {ReleaseMutex (m_hMutex);} private: HANDLE m_hMutex;}; class CSingleton {// other members public: static CSingleton * GetInstance () {if (m_pInstance = NULL) // determine whether the instance exists, no Lock handling {Lock (); if (m_pInstance = NULL) // determine whether to call {m_pInstance = new CSingleton () ;}unlock ();} return m _ for the first time _ PInstance;} private: CSingleton () {}; static CSingleton * m_pInstance; class CGarbo // Its only job is to delete the CSingleton instance {public: ~ In the destructor :~ CGarbo () {if (CSingleton: m_pInstance) delete CSingleton: m_pInstance ;}// defines a static member. When the program ends, the system automatically calls its destructor Static CGabor Garbo ;};
In this way, through the first layer of judgment, we do not need to lock the thread every time, but only lock the instance when it is not created; at the same time, it can also ensure the security of multithreading. This method is called Double-Check-Locking ).
The above is my understanding of the singleton mode. In this process, I have read a lot of materials, learned a lot, and gained a deeper understanding of the singleton model.
"I want to climb up step by step and fly forward on the blade at the highest point. The tears and sweat of a small day, one day I will belong to my day ." -- Snail mail