Singleton mode in C ++)

Source: Internet
Author: User

The Singleton mode is also called the singleton mode and the singleton mode. It may be the most widely used design mode. The intention is to ensure that a class has only one instance, and provide a global access point to access it, the instance isProgramModule sharing. There are many areas where such functional modules are needed, such as system log output. GUI applications must be single-mouse, modem connections need one and only one telephone line, and the operating system can only have one window manager, a pc is connected to a keyboard.

 

Singleton mode has many implementation methods. In C ++, you can even use a global variable to do this.CodeObviously not elegant. You can use global objects to access instances conveniently, but you cannot declare only one object. That is to say, you can still createLocal instance.

The design pattern book provides a very good implementation and definesSingleton type, UsePrivate Static pointer variablePoint to a unique instance of the class and usePublic static methodObtain the instance.

The Singleton mode manages its unique instances through the class itself. This feature provides a solution to the problem. A unique instance is a common object of A Class. When designing this class, you can only create one instance and provide global access to this instance. Singleton, a unique instance type, hides the operation for creating an instance in the static member function. Traditionally, this member function is called instance (). Its return value is the pointer of a unique instance.

Definition:

Class csingleton

{

// Other members

Public:

Static csingleton * getinstance ()

{

If (m_pinstance = NULL) // determines whether the first call is successful.

M_pinstance = new csingleton ();

Return m_pinstance;

}

PRIVATE:

Csingleton (){};

Static csingleton * m_pinstance;

};

Note: The following code must be provided in CPP:

Singleton * singleton: instance = NULL; 

Only the getinstance () member function is used to access a unique instance. If you do not use this function, any attempt to create an instance will fail because the class constructor is private. Use getinstance ()Lazy InitializationThat is to say, its return value is created when this function is accessed for the first time. This is a bulletproof Design -- all calls after getinstance () return pointers of the same instance:

Csingleton * P1 = csingleton: getinstance ();

Csingleton * P2 = p1-> getinstance ();

Csingleton & ref = * csingleton: getinstance ();

With a slight modification to getinstance, this design template can be applied to situations where multiple instances can be changed. For example, a class allows a maximum of five instances.

 

The Singleton class csingleton has the following features:

It has a static pointer m_pinstance pointing to a unique instance and is private;

It has a public function that obtains the unique instance and creates the instance as needed;

Its constructor is private, so that you cannot create instances of this class elsewhere.

 

Most of the time, this implementation will not be faulty. Experienced readers may ask when the space pointed to by m_pinstance will be released? The more serious problem is, when will the destructor of the instance be executed?

If there are necessary operations in the class destructor, such as closing the file and releasing external resources, the above Code cannot meet this requirement. We need a method to delete the instance normally.

You can call getinstance () at the end of the program and delete the returned pointer. This can implement functions, but it is not only ugly, but also 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 methodIt is to let this class know to delete itself at the right time, or to put the delete operation on a suitable point in the operating system, so that it can be automatically executed at the right time.

We know that when the program ends, the system willAutomatically 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 cgarbo class in the following code (Garbo stands for spam workers ):

Class csingleton

{

// Other members

Public:

Static csingleton * getinstance ();

PRIVATE:

Csingleton (){};

Static csingleton * m_pinstance;

Class cgarbo // Its only job is to delete the csingleton instance in the destructor.

{

Public:

~ Cgarbo ()

{

If (csingleton: m_pinstance)

Delete csingleton: m_pinstance;

}

}

Static cgabor Garbo; // defines a static member. When the program ends, the system automatically calls its destructor.

};

Class cgarbo is defined as the private embedded class of csingleton to prevent this class from being abused elsewhere.

When the program runs, the system calls the Garbo destructor, a static member of csingleton. This destructor deletes the unique instance of a single instance.

Releasing a singleton object in this way has the following features:

Define a proprietary nested class within the singleton class;

Define Private Static members dedicated for release in the singleton class;

The program analyzes the global variables at the end and selects the final release time;

The Singleton Code does not require any operation and does not need to care about the release of objects.

(Source: http://hi.baidu.com/csudada/blog/item/208fb0f56bb61266dcc47466.html)

Further discussion

However, it is always unsatisfactory to add a static object of a class, so some people use the following method to reproduce the problem of implementing singleton and solving it. The Code is as follows:

Class csingleton

{

// Other members

Public:

Static Singleton & getinstance ()

{

Static Singleton instance;

Return instance;

}

PRIVATE:

Singleton (){};

};

The use of local static variables is a very powerful method to fully implement the single-instance features, and the amount of code is less, there is no need to worry about the single-instance Destruction problem.

However, this method may also cause problems. When the following method is used as a Singleton,

Singleton = singleton: getinstance ();

In this case, a copy class problem occurs, which violates the features of the singleton instance. This problem occurs because the compiler generates a default constructor for the class to support copying the class.

Finally, there is no way. We need to disable copying classes and assigning values to classes, and prohibit programmers from using Singleton instances in this way. At that time, the leading means that the getinstance () function returns a pointer instead of a reference, the function code is changed to the following:

Static Singleton * getinstance ()

{

Static Singleton instance;

Return & instance;

}

But I always think it's not good. Why don't the compiler do this. This reminds me of the declarative class copy constructor that can be displayed, and the overload = Operator. The new Singleton class is as follows:

Class Singleton

{

// Other members

Public:

Static Singleton & getinstance ()

{

Static Singleton instance;

Return instance;

}

PRIVATE:

Singleton (){};

Singleton (const Singleton &);

Const Singleton & operator = (const Singleton &);

};

For the singleton (const Singleton &); and const Singleton & operator = (const Singleton &); functions, we need to declare them as private and declare them as not implemented. In this way, if the preceding method is used to use a Singleton, the compiler reports an error, whether in the youyuan class or other methods.

I don't know if such a singleton class still has problems, but there is almost no problem in using it in the program.

(Source: http://snailbing.blogbus.com/logs/45398975.html)

Optimized Singleton class for single-threaded applications

Singleton uses the new operator to allocate storage space for a unique instance. Because the new operator is thread-safe, you can use this design template in multi-threaded applications, but there isDefects: The instance must be manually destroyed with Delete before the application is terminated. Otherwise, not only memory overflow, but also unpredictable behavior, because the singleton destructor will not be called at all. By replacing dynamic instances with local static instances, a single-threaded application can easily avoid this problem. The following is a slightly different implementation from the above getinstance (), which is specially used for single-threaded applications:

Csingleton * csingleton: getinstance ()

{

Static csingleton inst;

Return & inst;

}

The local static object instance inst is constructed when getinstance () is called for the first time and remains active until the application is terminated. The pointer m_pinstance becomes redundant and can be deleted from the class definition, unlike dynamic objects, static objects are automatically destroyed when the application ends, so you do not have to manually destroy the instance.

(Source: http://blog.csdn.net/pingnanlee/archive/2009/04/20/4094313.aspx)

Code Learning (from http://developer.hi.baidu.com/#/detail/32113057reference)

 

[CPP] View plaincopy

  1. // Version 1
  2. # Include <iostream>
  3. Using NamespaceSTD;
  4. // C ++ implementation of the Singleton class
  5. ClassSingleton
  6. {
  7. Private:
  8. Singleton ();// Note: the constructor is private.
  9. StaticSingleton * instance;// Unique instance
  10. IntVaR;// Member variable (for testing)
  11. Public:
  12. StaticSingleton * getinstance ();// Factory method (used to obtain an instance)
  13. IntGetvar ();// Obtain the VaR value
  14. VoidSetvar (Int);// Set the value of VaR
  15. Virtual~ Singleton ();
  16. };
  17. // Constructor implementation
  18. Singleton: Singleton ()
  19. {
  20. This-> Var = 20;
  21. Cout <"Singleton constructor"<Endl;
  22. }
  23. Singleton ::~ Singleton ()
  24. {
  25. Cout <"Singleton destructor"<Endl;
  26. // Delete instance;
  27. }
  28. // Initialize static members
  29. /* Singleton * singleton: instance = NULL; 
  30.  
  31. Singleton * singleton: getinstance () 
  32.  
  33.  
  34. If (null = instance) 
  35.  
  36. Instance = new Singleton (); 
  37.  
  38. Return instance; 
  39.  
  40. }*/
  41. Singleton * singleton: instance =NewSingleton;
  42. Singleton * singleton: getinstance ()
  43. {
  44. ReturnInstance;
  45. }
  46. // Seter & getter content
  47. IntSingleton: getvar ()
  48. {
  49. Return This-> Var;
  50. }
  51. VoidSingleton: setvar (IntVaR)
  52. {
  53. This-> Var = var;
  54. }
  55. // Main
  56. VoidMain ()
  57. {
  58. Singleton * ton1 = singleton: getinstance ();
  59. Singleton * ton2 = singleton: getinstance ();
  60. If(Ton1 = ton2)
  61. Cout <"Ton1 = ton2"<Endl;
  62. Cout <"Ton1 Var ="<Ton1-> getvar () <Endl;
  63. Cout <"Ton2 Var ="<Ton2-> getvar () <Endl;
  64. Ton1-> setvar (150 );
  65. Cout <"Ton1 Var ="<Ton1-> getvar () <Endl;
  66. Cout <"Ton2 Var ="<Ton2-> getvar () <Endl;
  67. DeleteSingleton: getinstance ();// Must be explicitly deleted
  68. }

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.