zoukankan      html  css  js  c++  java
  • C++ 单例模式

    单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

    简单实现:

     1 #include <iostream>
     2 #include <cstdlib>
     3 
     4 using namespace std;
     5 
     6 class CSingleton{
     7 private:
     8     CSingleton(){
     9         cout << "construct function" << endl;
    10     }
    11     static CSingleton *p_Instance;
    12 public:
    13     static CSingleton *GetInstance(){
    14         if(p_Instance == NULL){
    15             p_Instance = new CSingleton();
    16             cout << "Construct a instance " << endl;
    17         }
    18         return p_Instance;
    19     }
    20 };
    21 
    22 CSingleton *CSingleton::p_Instance = NULL;
    23 
    24 int main()
    25 {
    26     CSingleton *p = CSingleton::GetInstance();
    27     system("pause");
    28     return 0;
    29 }

    上述方法代码容易实现,但存在一个问题,即是内在泄漏,由new申请的内存并没有得到释放

    为了让实例自动释放内存,可在类CSingleton内部定义一个垃圾回收类,同时定义一个该类的静态成员,当程序运行结束,系统自动析构此静态成员时,在析构函数中会释放CSingleton实例。

     1 #include <iostream>
     2 #include <cstdlib>
     3 
     4 using namespace std;
     5 
     6 class CSingleton{
     7 private:
     8     CSingleton(){
     9         cout << "construct function" << endl;
    10     }
    11     static CSingleton *p_Instance;
    12 
    13     //垃圾回收类
    14     class GCarbo{
    15     public:
    16         GCarbo(){ cout << "construct GCarbo" << endl;}
    17         ~GCarbo()
    18         {
    19             cout << "destruct GCarbo" << endl;
    20             if(p_Instance != NULL){
    21                 delete p_Instance;
    22                 p_Instance = NULL;
    23                 cout << "release memory succeed ! " << endl;
    24                 system("pause"); //不暂停看不到输出信息
    25             }
    26         }
    27     };
    28     static GCarbo gc;
    29     
    30 public:
    31     static CSingleton *GetInstance(){
    32         if(p_Instance == NULL){
    33             p_Instance = new CSingleton();
    34             cout << "Construct a instance " << endl;
    35         }
    36         return p_Instance;
    37     }
    38 };
    39 
    40 CSingleton *CSingleton::p_Instance = NULL;
    41 //类的静态数据成员需要类外部进行初始化,以创建GCarbo类的一个实例
    42 CSingleton::GCarbo CSingleton::gc; 
    43 
    44 int main()
    45 {
    46     CSingleton *p = CSingleton::GetInstance();47     return 0;
    48 }

    上述方法虽然解决了内存泄漏问题,但在多线程环境下,如当两个线程同时调用GetInstance()方法时,执行到if(p_Instance == NULL)时,都为真,然后两个线程都得到一个实例,两个指针并不是指向同一个地方,这不满足单例模式定义

    解决方法:(加锁实现同步)

     1 //其他代码同上
     2 static CSingleton *GetInstance(){
     3         //这里采用Double-Check Locking(双重锁定)
     4         //第一个if语句使实例未被创建时候再加锁处理,而不是每次调用GetInstance()方法就会判断锁,若已创建实例则直接退出
     5         //第二个if语句,使获得锁的线程在创建实例后,不能再创建新的实例,以满足单例目的
     6         if(p_Instance == NULL){
     7             Lock();
     8             if(p_Instance == NULL){
     9                 p_Instance = new CSingleton();
    10                 cout << "Construct a instance " << endl;
    11             }
    12             UnLock();
    13         }
    14         return p_Instance;
    15     }

    参考:

    http://www.2cto.com/kf/201403/283007.html

    http://blog.csdn.net/roy1261/article/details/51425987

    只为训练自己,时刻锤炼一个程序员最基本的技能!
  • 相关阅读:
    Flash向量1点和向量
    Flash/Flex学习笔记(2):捕获摄像头
    Flash向量0序言
    Flash向量3加法和投影
    Flash/Flex学习笔记(3):动态添加组件
    Flash/Flex学习笔记(5):捕获摄像头(续)在线抓屏并保存到客户端本地
    异常写法
    关于存储过程得传出参数的错误
    python Beautiful Soup模块的安装
    python学习笔记比较全
  • 原文地址:https://www.cnblogs.com/coding-wtf/p/5940083.html
Copyright © 2011-2022 走看看