导航

c++单例模式

Posted on 2017-11-16 17:32  困或  阅读(278)  评论(0编辑  收藏  举报

1.功能:

  只能有一个实例的类,用于类似计数、内存池的情况。

2.实现方法:

  [1]构造函数设置为private,因此不能在外部创建实例。

  [2]提供一个public方法访问实例。

  [3]析构函数,析构函数是为了销毁这个类的成员变量,private和public都可以,但是析构函数里面不能delete这个类的实例(析构函数里面delete实例本身就是有问题的,因为delete会调用析构函数,析构里面又delete,会造成递归)。

  [4]实例销毁方法:一种是定义一个垃圾回收类,自动销毁这个实例;一种是在外面手动delete这个实例;还一种是定义为访问函数里面的静态成员,当程序退出的时候自动释放这个实例。

3.代码实现:

  [1]函数内部静态成员变量方式,第一次访问的时候创建实例,并且线程安全:

 1 #include <iostream>  
 2 #include <stdio.h>  
 3 using namespace std;  
 4   
 5 class singleton  
 6 {  
 7 public:  
 8     static singleton *get_instance(){  
 9         static singleton single;
10         return &single;
11     }  
12 private:  
13     singleton(){
14         printf("singleton() called.\n");
15     }
16 
17     ~singleton(){
18         printf("~singleton() called.\n");
19     }  
20 };  
21   
22 
23 int main(int argc, char *argv[])  
24 {  
25     singleton *s = singleton::get_instance();  
26     return 0;  
27 }  

 输出:

 

   [2]使用静态的成员变量方式,第一次访问的时候创建实例,并且添加了垃圾回收类:

 1 #include <iostream>  
 2 #include <stdio.h>  
 3 using namespace std;  
 4   
 5 class singleton  
 6 {  
 7 public:  
 8     static singleton *get_instance(){  
 9         if(m_instance == NULL){  
10             m_instance = new singleton();  
11             printf("get_instance() called.\n");
12         }  
13         
14         return m_instance;  
15     }  
16     
17     ~singleton(){
18         printf("~singleton() called.\n");
19     }  
20   
21 private:  
22     singleton(){
23         printf("singleton() called.\n");
24     }  
25     
26     class gc
27     {  
28     public:  
29         gc(){  
30             printf("gc() called.\n");
31         }
32         
33         ~gc(){  
34             printf("~gc() called.\n");
35             if(m_instance != NULL){  
36                 delete m_instance;  
37                 m_instance = NULL;  
38             }  
39         }
40     };  
41     
42     static gc m_gc;
43     static singleton *m_instance;  
44 };  
45   
46 singleton *singleton::m_instance = NULL;  
47 singleton::gc singleton::m_gc;
48 
49 int main(int argc, char *argv[])  
50 {  
51     singleton *s = singleton::get_instance();  
52     return 0;  
53 }  

输出:

4.说明:

  [1]上面的两种方式没有好坏之分,只是不同的实现方式,其他还有各种方式实现单实例,但是都没什么区别。

  [2]关于析构函数,因为private类型的析构函数无法在外部使用delete对象,所以准备在外面手动释放这个类的实例和其他内部成员时,应该把析构函数设置为public,如果想让这个类的所有成员必须在类内部释放(类里面的垃圾回收类中释放),则应该把析构函数设置为private。

  [3]多线程使用,就是加上锁处理m_instance实例,和常规的多线程没什么区别。