Singleton mode is the implementation of a singleton class, that is, a class in the system has only one instance, and the instance is easy to access outside. This facilitates the control of the number of instances and saves system resources.
In the case of simple and non-local static objects, for these objects, the program is difficult to control, for these existing and global, and generally persistent objects, sometimes need to follow a certain constraint or order to initialize, and the initialization of these objects without using a singleton method will be extremely insecure. This is the time to use a singleton pattern to solve this problem.
There are many ways to implement a singleton, and the simplest one is to put an object in a function as its static member:
Class SingleTon; singleton* getsingletoninstance () {static singleton* instance = new SingleTon (); return instance;} Class Singleton{friend singleton* getsingletoninstance ();p Rivate:singleton () {}};
This is the simplest way to implement a singleton pattern, and the disadvantage is that the function that gets the singleton object is not in the class. The first thing to do is to implement a singleton pattern, declare the constructor as rare, so that the constructor cannot be used by the method, nor can it create an object of the Singleton class at will. And here gets the instance as a function of the static object, so there is only one, and the time of creation to the end of the program.
Of course, you can also change the static object in the function to a static object in the class, and set the global function as a static function in the class, thus getting a more commonly used form:
Class Singleton{public:static singleton* getinstance () {static singleton* instance = new SingleTon (); return instance;} ~singleton () {}private:singleton () {}singleton (const singleton&); singleton& operator= (const singleton&);};
Static members in a function are also used here, and it is also possible to use static members in a class:
Class Singleton{public:static singleton* getinstance () {if (NULL = = Instance) instance = new SingleTon (); return instance;} Private:singleton () {}singleton (const singleton&); singleton& operator= (const singleton&); static singleton* instance;}; singleton* singleton::instance;//= new SingleTon (); Static member initialization within a class can call a private constructor in a class.
For security purposes, both the copy constructor and the assignment operator are hidden, but the destructor is still visible, and the programmer will misuse the delete to delete the singleton entity, which is unsafe, you can choose to put the destructor in private, hide the destructor, and for some objects at the end of the destruction, Do not care about the release process.
However, if the destructor is called in the execution of the program to delete the instance, a public function is used to encapsulate the destructor, and the destructor is set to private:
Class Singleton{public:static singleton* getinstance () {if (NULL = = Instance) instance = new SingleTon (); return instance;} static void Delelteinstance () {if (null! = instance) {Delete instance;instance = NULL;}} Private:singleton () {}singleton (const singleton&); singleton& operator= (const singleton&); static singleton* Instance;~singleton ();}; singleton* singleton::instance;
Here is basically a single-threaded security, and then consider multi-threading, when multiple threads attempt to initialize a singleton instance at the same time, there is a problem, to use mutual exclusion to solve the problem, here use the critical section to solve:
critical_section cs;class singleton{public:static singleton* getinstance () {if (NULL = = Instance) {EnterCriticalSection (&CS); if (NULL = = instance) {//double check lock, after entering the critical section again to detect if the object has been established instance = new SingleTon ();} LeaveCriticalSection (&CS); } return instance;} static void Delelteinstance () {if (null! = instance) {entercriticalsection (&CS); if (null! = instance) {Delete instance ; instance = NULL;} LeaveCriticalSection (&CS); }} Private:singleton () {}singleton (const singleton&); singleton& operator= (const singleton&); static singleton* Instance;~singleton ();}; singleton* singleton::instance;
The use of double check lock mechanism, the first is to determine whether to operate the instance, the second is to enter the critical section of the data after the lock, to determine whether the data is no longer disturbed by the outside world, the first judgment and the second judgment between the operation of other threads, so two times to ensure the security of the instance.
But this is still not safe enough, because there are still some special cases in the multi-threading, some files in the class are locked, such as file handle, database connection, etc., these will not close the resource immediately when the program shuts down and must be released manually before the program shuts down. This is not automatically closed, for the destructor is private, because the system cannot access the private destructor, for the absence of these connections, that is, the class only occupies some address in memory, the system treats it as a global variable, at the end of the memory resource is freed, so there is no memory leak. And if the class has file handles and database connections, the system does not help to close these, so you must manually call the destructor to close the files.
In this case, a private embedded class Garbo is generally used, meaning garbage workers, in a singleton class contains a private static garbage worker object, when the program ends, the system will call the object's destructor, and this destructor in the case of a single class object implementation of the destructor.
critical_section cs;class singleton{public:static singleton* getinstance () {if (NULL = = Instance) {EnterCriticalSection (&CS); if (NULL = = instance) {//double check lock, after entering the critical section again to detect if the object has been established instance = new SingleTon ();} LeaveCriticalSection (&CS); } return instance;} static void Delelteinstance () {if (null! = instance) {entercriticalsection (&CS); if (null! = instance) {Delete instance ; instance = NULL;} LeaveCriticalSection (&CS); }} Private:singleton () {}singleton (const singleton&); singleton& operator= (const singleton&), static singleton* Instance;~singleton () {}//corresponding shutdown connection class garbo{ Public:~garbo () {if (null! = instance) {entercriticalsection (&CS); if (null! = instance) {Delete Instance;instance = NULL;} LeaveCriticalSection (&cs);}} ; Static GarBo GC;}; singleton* singleton::instance; Singleton::garbo singleton::gc;//out-of-class initialization.
This gives you a perfect singleton class.
C + + implementation of design Patterns 1. Singleton mode