Design Mode-singleton Mode

Source: Internet
Author: User

Singleton mode:
Make sure that only one object is generated when a class of the program is running, and you have the access permission to it similar to the Global object.

 


Mode Analysis:
For example, when writing a program, we often have management classes like DriverManager and CallManager. Their main function is to manage a bunch of similar objects. For such a management class, a program generally has only one object. After all, the purpose of writing a management class is to facilitate management, and when there are more management objects, the meaning of management is lost, in addition, we certainly need to directly access this object in many places in the program. After all, a program needs to find the corresponding Driver and Call through the management class in many places.

 


Solution:
1. The simplest way is to define a global object.
Use CallManager g_CallManager; to create a global object, and then use extern CallManager g_CallManager; to obtain its access permissions. It sounds good, but from the first time we write a program, there will be many experienced veterans who tell us the drawbacks of global objects, and we cannot ensure that there is only one object, after all, you can use code like CallManager myManager to create objects in your code at any time.
2. Singleton Mode
[Cpp]
Class CallManager
{
Public:
Static CallManager * GetInstance (){
If (instance _ = NULL) {// note that this object is created only during the first call
Instance _ = new CallManager ();
}
Return instance _;
}
Private:
Static CallManager * instance _; // note that this is a static private object
CallManager (); // note that this is private
}

Class CallManager
{
Public:
Static CallManager * GetInstance (){
If (instance _ = NULL) {// note that this object is created only during the first call
Instance _ = new CallManager ();
}
Return instance _;
}
Private:
Static CallManager * instance _; // note that this is a static private object
CallManager (); // note that this is private
}
[Cpp]
Static CallManager * CallManager: instance _ = NULL;

Static CallManager * CallManager: instance _ = NULL; analysis:
To ensure that you cannot create an object externally through other similar schemes such as CallManager myManager, the constructor defines the object as private, so that external explicit object creation is prohibited, it cannot be compiled at all. Then you may ask, How can I create an object? After all, I still need an object. The powerful GetInstance method appears. It accesses the static member instance _ of its class to determine whether to create an object. This gives us two guarantees: 1. You can create an object, you can create only one object. 2. You can access this object anywhere else and use the GetInstance method. If you are not familiar with static member variables and static data members, you are advised to find some relevant documents for further understanding. The static member variable instance _ gives us a class with only one variable. The static member function GetInstance gives us the right to access the private static member variable instance, at the same time, only one object is created.
Extension:
1. If you know multithreading, you should find the problem with the code above. If the GetInstance method is called in two places at the same time, it is possible to create two times at the same time, this is not advisable. The usual solution is to call the GetInstance method once during system initialization to ensure that the object is created. I think this method is very good, rather it is not recommended to use lock, because this method will be used in many places, adding lock will seriously affect the original efficiency.
2. When will new CallManager be released? In this case, we recommend that you create another static Destory method and delete instance _.
[Cpp]
Static void DestroyInstance (){
Delete instance _;
Instance _ = NULL;
}

Static void DestroyInstance (){
Delete instance _;
Instance _ = NULL;
}
3. Calling DestroyInstance is a little complicated. After all, you need to consider where to call the instance. If an exception occurs, no call, and so on, you should give it to the system. Use a local static object.
[Cpp]
Public:
CallManager * GetInstance (){
Static CallManager localManager;
Return & localManager;
}

Public:
CallManager * GetInstance (){
Static CallManager localManager;
Return & localManager;
} With this local static usage, DestroyInstance is not only called, but also released and the instance _ member variable is saved. Why not? Recommended.
However, you still need to note that GetInstance still needs to be called once for initialization, avoiding the trouble of multithreading. Some static objects will only be allocated memory for the first call, this conclusion can be verified by printing logs on the Callma constructor.


Static variable version:
[Cpp]
# Include <stdio. h>
Class CallManager
{
Public:
Static CallManager * GetInstance (){
Static CallManager localManager;
Return & localManager;
}
~ CallManager (){
Printf ("CallManager Destructed... \ n ");
}
Private:
CallManager () {// note that this is private
Printf ("CallManager Constructed... \ n ");
}
};

# Include <stdio. h>
Class CallManager
{
Public:
Static CallManager * GetInstance (){
Static CallManager localManager;
Return & localManager;
}
~ CallManager (){
Printf ("CallManager Destructed... \ n ");
}
Private:
CallManager () {// note that this is private
Printf ("CallManager Constructed... \ n ");
}
}; Please note that although I wrote the implementation of the function in the class declaration, please note that this is not my intention. I want to make it simple. In fact, it should be divided into h and cpp files, which can reduce the compilation dependency, and the default inline is not what we want. The details will not be repeated.
Main DRIVER:
[Cpp]
# Include <assert. h>
# Include <CallManager. h>
Int main (){
CallManager * pCallManager = CallManager: GetInstance ();
CallManager * pCallManager2 = CallManager: GetInstance ();
Assert (pCallManager = pCallManager2); // confirm that it is exactly the same
Return 0;
}

# Include <assert. h>
# Include <CallManager. h>
Int main (){
CallManager * pCallManager = CallManager: GetInstance ();
CallManager * pCallManager2 = CallManager: GetInstance ();
Assert (pCallManager = pCallManager2); // confirm that it is exactly the same
Return 0;
}
Output result:
[Cpp]
CallManager Constructed...
CallManager Destructed...

CallManager Constructed...
CallManager Destructed... is consistent with what we think. It is built only once by initialization and automatically released after the main ends. Wonderful.


Postscript:
I don't know if my narrative method will be too colloquial. I just want to talk about what I learned when I learned it, some experiences hope to help you even a little. The process described is also a process where I review my ideas again. If you have any mistakes, please point them out and let me correct my mistakes. Thank you.

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.