A singleton pattern in C + +

Source: Internet
Author: User

The singleton mode, also known as the single-piece mode, the list mode, is probably the most widely used design pattern. The intent is to ensure that a class has only one instance, and provides a global access point to it, which is shared by all program modules. There are a lot of places need this function module, such as the log output of the system, GUI application must be single mouse, modem connection need one and only need a telephone line, the operating system can only have a form manager, a PC with a keyboard.
There are many implementations of the singleton pattern, which can even be done directly with a global variable in C + +, but this code is remarkably elegant. Using global objects guarantees easy access to the instance, but there is no guarantee that only one object is declared-that is, in addition to a global instance, a local instance of the same class can still be created.
In design mode, a very good implementation is given, defining a singleton class that uses the class's private static pointer variable to point to a unique instance of the class and obtains the instance with a public static method.
The singleton pattern manages its only instance through the class itself, which provides a way to solve the problem. The only instance is a generic object of the class, but when designing this class, let it simply create an instance and provide global access to this instance. The unique instance class singleton hides the operation that created the instance in a static member function. It is customary to call this member function instance (), whose return value is a pointer to a unique instance.

Definitions such as the following:

Class Csingleton{private:csingleton ()   //constructor is private {}static Csingleton *m_pinstance;public:static Csingleton * GetInstance () {if (m_pinstance = = NULL)  //Infer whether the first call to M_pinstance = new Csingleton (); return m_pinstance;};
The only way for users to access the unique instance is with the getinstance () member function. Assuming that this function is not passed, any attempt to create an instance will fail, because the class's constructor is private. getinstance () uselazy initialization, which means that its return value is created when the function is first visited.. This is a bulletproof design--all getinstance () after the call returns a pointer to the same instance:

csingleton* P1 = Csingleton:: getinstance ();
csingleton* P2 = p1->getinstance ();
Csingleton & ref = * Csingleton:: getinstance ();
With a slight change to the getinstance, this design template can be applied to a variable multi-instance scenario, such as a class agreeing to a maximum of five instances.

a singleton class Csingleton has the following characteristics:
It has aA static pointer to a unique instance m_pinstance, and is private;
It has a public function that gets the unique instance, and creates the instance when it is needed;
Its constructor is private so that an instance of the class cannot be created elsewhere.
Most of the time, this implementation does not fail. An experienced reader may ask, when does the space M_pinstance point to be released? The more serious question is, when does the destructor for the instance run?
Assuming that there is a necessary action in the destructor of the class, such as closing the file and releasing the external resource, the code above does not implement this requirement. We need a way to delete the instance normally.
Ability to call getinstance () at the end of the program and drop the delete operation on the returned pointer. This enables functionality, but is not only very ugly, and easy error. Since this extra code is very easy to forget, it is also very difficult to guarantee that after the delete, there is no code to call the GetInstance function again.
a good way to do this is to let the class know to delete itself at the right time, or to suspend its operation on an appropriate point in the operating system .So that it is self-active at the right time.
We knowat the end of the program, the system will actively deconstruct all global variables .。 In factThe system also reconstructs static member variables for all classes, just as these static members are also global variables。 Using this feature, we are able to define a single instance of thisStatic member variables, and it'sThe only jobis to delete an instance of the Singleton class in the destructor. The Cgarbo class in the following code (garbo means garbage worker):
Class Csingleton{private:csingleton () {}static Csingleton *m_pinstance;class Cgarbo   // Its only job is to delete the instance of Csingleton in the destructor {Public:~cgarbo () {if (csingleton::m_pinstance) delete csingleton::m_pinstance;}}; Static Cgarbo Garbo;  Define a static member variable, at the end of the program, the system will voluntarily call its destructor public:static Csingleton * getinstance () {if (m_pinstance = = NULL)  //Infer whether the first call m _pinstance = new Csingleton (); return m_pinstance;}};
The class Cgarbo is defined as a private inline class of Csingleton, in case the class is abused elsewhere.
At the end of the program execution, the system invokes the destructor of the static member Garbo of Csingleton, which removes the singleton unique instance.
Using this method to release a singleton object has the following characteristics:
Define a proprietary nested class within a singleton class;
Defining a private static member specifically for release within a singleton class;
Using the program at the end of the analysis of the characteristics of global variables, choose the final release time;
Using a singleton code does not require any action or concern about the object's release.

A further discussion

But adding a static object to a class is always a bit uncomfortable, so someone uses one of the following methods to implement the singleton and solve its corresponding problem again, such as the following code:

Class Csingleton{private:csingleton ()   //constructor is private {}public:static Csingleton & getinstance () {static Csingleton instance;   Local static variable return instance;}};
The use of local static variables , a very powerful method, fully realize the characteristics of a single case, and the code is less, do not worry about single-instance destruction problems.
However, the use of this method will also fail, when the following methods such as the use of a single case,
Singleton Singleton = Singleton:: getinstance ();
In doing so, there is a problem with a copy of the class , which violates the characteristics of the singleton. The problem arises because the compiler generates a default constructor for the class to support a copy of the class.

Finally there is no way, we want to prohibit the class copy and class assignment, prohibit the program ape in such a way to make use of Singleton, then the leader means that the getinstance () function returns a pointer instead of returning a reference, the code of the function is changed to such as the following:

Class Csingleton{private:csingleton ()   //constructor is private {}public:static Csingleton * getinstance () {static Csingleton instance;   Local static variable return &instance;}};

But I always feel bad, why not let the compiler do not do it. It was then that I remembered the constructors that could be displayed for the declaration class copy, and the overloaded = operator, the new Singleton class such as the following:

Class Csingleton{private:csingleton ()   //constructor is private {}csingleton (const Csingleton &); Csingleton & operator = (const Csingleton &);p ublic:static Csingleton & getinstance () {static Csingleton Insta nce;   Local static variable return instance;}};
about Singleton (const Singleton), and Singleton & operate = (const singleton&), functions that need to be declared private and simply declared not implemented. In this way, if you use the above method to make a single case, whether in the friend class or other, the compiler is an error.
I do not know if this singleton class will still have problems, but in the program this kind of use has basically no problem.

For thread safety and exception security, the following extensions can be made
Class Lock{private:       ccriticalsection m_cs;public:lock (ccriticalsection  CS): M_cs (CS) {M_cs. Lock ();} ~lock () {M_cs. Unlock ();}}; Class Singleton{private:singleton (); Singleton (const Singleton &); singleton& operator = (const Singleton &);p ublic:static Singleton *instantialize (); static Singleton *pinstance; Static CCriticalSection CS;}; singleton* Singleton::p instance = 0; singleton* Singleton::instantialize () {if (pinstance = = NULL) {   //double Checklock Lock (CS);           Using lock for thread safety, using resource management classes to achieve exception security//using Resource management classes, when throwing exceptions, the resource management class object will be destroyed, whether it is due to exception thrown or the end of the statement block. if (pinstance = = NULL) {pinstance = new Singleton ();}} return pinstance;}

The reason why the Instantialize function inside the pinstance is null to make two inferences, because the method called once the object is generated, pinstance = = NULL Most of the time is false, assuming that the original method, each acquisition of the instance needs to be locked, Efficiency is too low. The improved method only needs to be locked at the time of the first call, which can greatly improve the efficiency.


A singleton pattern in C + +

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.