C ++ perfectly implements the Singleton Mode

Source: Internet
Author: User

The Singleton mode is one of the common design patterns, but it is not easy to implement a practical design pattern.
Standard Implementation
1 class Singleton
2 {
3 public:
4 static Singleton * Instance ()
5 {
6 if (0 = _ instance)
7 {
8 _ instance = new Singleton;
9}
10 return _ instance;
11}
12 protected:
13 Singleton (void)
14 {
15}
16 virtual ~ Singleton (void)
17 {
18}
19 static Singleton * _ instance;
20 };
This is the method used in textbooks. It seems that there are no problems, but there are actually many problems. Next we will solve it one by one.
Question 1: automatic garbage collection
The above program must remember to release the memory at the end of the program. To let it automatically release the memory, we introduce auto_ptr to change it.
1 # include <memory>
2 # include <iostream>
3 using namespace std;
4 class Singleton
5 {
6 public:
7 static Singleton * Instance ()
8 {
9 if (0 = _ instance. get ())
10 {
11 _ instance. reset (new Singleton );
12}
13 return _ instance. get ();
14}
15 protected:
16 Singleton (void)
17 {
18 cout <"Create Singleton" <endl;
19}
20 virtual ~ Singleton (void)
21 {
22 cout <"Destroy Singleton" <endl;
23}
24 friend class auto_ptr <Singleton>;
25 static auto_ptr <Singleton> _ instance;
26 };
27 // Singleton. cpp
28 auto_ptr <Singleton> Singleton: _ instance;
Question 2 Add a template
In one of my projects, there are multiple Singleton classes. For Singleton classes, I want to implement all the above, which makes me feel bored. So I thought of a template to complete these duplicates.
Repeat the work.
Now we want to add the most attractive single-piece implementation in this article:
1 # include <memory>
2 using namespace std;
3 using namespace C2217: Win32;
4
5 namespace C2217
6 {
7 namespace Pattern
8 {
9 template <class T>
10 class Singleton
11 {
12 public:
13 static inline T * instance ();
14
15 private:
16 Singleton (void ){}
17 ~ Singleton (void ){}
18 Singleton (const Singleton &){}
19 Singleton & operator = (const Singleton &){}
20
21 static auto_ptr <T> _ instance;
22 };
23
24 template <class T>
25 auto_ptr <T> Singleton <T>: _ instance;
26
27 template <class T>
28 inline T * Singleton <T>: instance ()
29 {
30 if (0 = _ instance. get ())
31 {
32 _ instance. reset (new T );
33}
34
35 return _ instance. get ();
36}
37
38 // Class that will implement the singleton mode,
39 // must use the macro in it's delare file
40 # define DECLARE_SINGLETON_CLASS (type )\
41 friend class auto_ptr <type> ;\
42. friend class Singleton <type>;
43}
44}
Question 3 thread security
The above program can adapt to a single-threaded program. However, a problem occurs if you use a multi-threaded program. The main problem is to execute _ instance. reset (new T) at the same time );
Two new objects will be generated at the same time, and one will be released immediately, which is inconsistent with the intention of the Singleton mode. Therefore, you need a safer version:
1 # include <memory>
2 using namespace std;
3 # include "Interlocked. h"
4 using namespace C2217: Win32;
5
6 namespace C2217
7 {
8 namespace Pattern
9 {
10 template <class T>
11 class Singleton
12 {
13 public:
14 static inline T * instance ();
15
16 private:
17 Singleton (void ){}
18 ~ Singleton (void ){}
19 Singleton (const Singleton &){}
20 Singleton & operator = (const Singleton &){}
21
22 static auto_ptr <T> _ instance;
23 static CResGuard _ rs;
24 };
25
26 template <class T>
27 auto_ptr <T> Singleton <T>: _ instance;
28
29 template <class T>
30 CResGuard Singleton <T >:_ rs;
31
32 template <class T>
33 inline T * Singleton <T>: instance ()
34 {
35 if (0 = _ instance. get ())
36 {
37 CResGuard: CGuard gd (_ rs );
38 if (0 = _ instance. get ())
39 {
40_instance. reset (new T );
41}
42}
43 return _ instance. get ();
44}
45
46 // Class that will implement the singleton mode,
47 // must use the macro in it's delare file
48 # define DECLARE_SINGLETON_CLASS (type )\
49 friend class auto_ptr <type> ;\
50 friend class Singleton <type>;
51}
52}
The main function of the CresGuard class is thread access synchronization. The Code is as follows:
1 class CResGuard {
2 public:
3 CResGuard () {m_lGrdCnt = 0; InitializeCriticalSection (& m_cs );}
4 ~ CResGuard () {DeleteCriticalSection (& m_cs );}
5
6 // IsGuarded is used for debugging
7 BOOL IsGuarded () const {return (m_lGrdCnt> 0 );}
8
9 public:
10 class CGuard {
11 public:
12 CGuard (CResGuard & rg): m_rg (rg) {m_rg.Guard ();};
13 ~ CGuard () {m_rg.Unguard ();}
14
15 private:
16 CResGuard & m_rg;
17 };
18
19 private:
20 void Guard () {EnterCriticalSection (& m_cs); m_lGrdCnt ++ ;}
21 void Unguard () {m_lGrdCnt --; LeaveCriticalSection (& m_cs );}
22
23 // Guard/Unguard can only be accessed by the nested CGuard class.
24 friend class CResGuard: CGuard;
25
26 private:
27 CRITICAL_SECTION m_cs;
28 long m_lGrdCnt; // # of EnterCriticalSection cballs
29 };
Question 4 practical methods
For example, if you have a class that needs to implement the single-piece mode, you should implement it like this:
1 # include "singleton. h"
2 using namespace C2217: Pattern;
3
4 class ServiceManger
5 {
6 public:
7 void Run ()
8 {
9}
10 private:
11 ServiceManger (void)
12 {
13}
14 virtual ~ ServiceManger (void)
15 {
16}
17 DECLARE_SINGLETON_CLASS (ServiceManger );
18 };
19
20 typedef Singleton <ServiceManger> SSManger;
It is very simple to use, and it is no different from the general Singleton implementation method.
1 int _ tmain (int argc, _ TCHAR * argv [])
2 {
3 SSManger: instance ()-> Run ();
4}
The implementation of a simple Singleton mode shows the rich semantics hidden behind the C ++ language. I hope someone can implement a better Singleton for everyone to learn.

Related Article

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.