Sometimes the implementation of a class, but only need to create an instantiated object to complete the requirements, if there are too many objects not only waste memory space will also make the code data is not so good maintenance, so you will need to design a class can only generate one instance;
First, in order for the class to instantiate only one object, its constructor must not be arbitrarily called externally, so the access qualifier of the class's constructor should be set to private, but how do you get the only instantiated object? You can design a member function that can only allocate the memory space of a single object of that class, and return a pointer to that space to the requested object, so you can design the class as follows:
#include <iostream>using namespace std;class Singleton{private: singleton () {} singleton (Singleton& s ); singleton& operator= (singleton& s); public: static singleton*& getinstance () { if (_instance == null) { _instance = new singleton (); } return _instance; } ~singleton () { if (_instance != null) &NBSP;&NBsp; delete _instance; } private: static singleton *_instance;}; singleton* singleton::_instance = null;
The chestnut above the constructor, copy construction and the overloaded function of the assignment operator is set to the private access qualifier, the outside world cannot instantiate the object through these functions, and then designed a static member function, it is worth mentioning that the static member function does not have the implied this pointer, Therefore, the outside world can use the class name to add the domain access symbol:: To invoke the static member function ;
A member variable of a class defines only one _instance pointer to a class object, and a static member function can be initialized outside the class, first initialized to NULL, and _instance is null when the getinstance function is called for the first time, Thus allocating space for a class object and returning it, but when the function is called for the second time, _instance already has a value that does not allocate space but returns an instantiated object that already exists, so no matter how the call to the GetInstance function will only return the same address empty;
However, the above function in a single-threaded environment is not a problem, when there are multiple threads concurrently accessing the function, if two or more threads at the same time to get the value of the initialized null _instance to be judged, it is possible to judge the success, That is, it will be new out of two different address space, so it does not conform to the original intention of the design, so in the multi-threaded running environment, the code in the GetInstance function will become a critical section, that is, to have a mutually exclusive relationship, you can add mutex mutex:
Static singleton*& getinstance () {pthread_mutex_lock (&lock); if (_instance = = NULL) {_instance = new Singleton (); } pthread_mutex_unlock (&lock); return _instance;}
However, the above code is still a few efficiency problems, if a thread at the beginning of the lock and the success of the new space, then each time the thread into the function getinstance to fight for the lock resources and then to judge, so you can lock before the first judgment, if _ Instance is not empty, there is no need to compete for lock resources after the judgment, so the code can be optimized as follows:
Static singleton*& getinstance () {if (_instance = = NULL) {pthread_mutex_lock (&lock); if (_instance = = NULL) {_instance = new Singleton (); } pthread_mutex_unlock (&lock); } return _instance;}
In fact, in addition to the solution given above, there is another simple rough design, that is, directly to the static member variable _instance initialization is initialized to a new class of the instantiation of the object, and then each call getinstance function Fetch _ The value of the instance is returned directly:
Class Singleton{private:singleton () {} Singleton (singleton& s); singleton& operator= (singleton& s); Public:static singleton*& getinstance () {return _instance; } private:static Singleton *_instance;}; singleton* singleton::_instance = new Singleton ();
The above one-time to the object space to open up a direct return without judgment, this way is called a hungry man-type, equivalent to use space for time, and the front of a time when needed to judge and then open up space, this way is called lazy, the equivalent of time to change space, each has pros and cons.
Finish
This article is from the "Knock Code good Sleep zzz" blog, please be sure to keep this source http://2627lounuo.blog.51cto.com/10696599/1768753
Singleton mode in C + +--2