C++中的单例模式


转自:http://blog.csdn.net/hackbuteer1/article/details/7460019 程序员

单例模式是一种经常使用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。经过单例模式能够保证系统中一个类只有一个实例并且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。若是但愿在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。显然单例模式的要点有三个:一是某个类只能有一个实例;二是它必须自行建立这个实例;三是它必须自行向整个系统提供这个实例;设计模式

 单例模式其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被全部程序模块共享。ide

《设计模式》一书中给出了一种很不错的实现,定义一个单例类,使用类的私有静态指针变量指向类的惟一实例,并用一个公有的静态方法获取该实例。函数


class CSingleton
{private:
   CSingleton()   //构造函数是私有的  
     {
   }  
    static CSingleton *m_pInstance;
    public:    
    static CSingleton * GetInstance()
   {      
     if(m_pInstance == NULL)  //判断是否第一次调用
           
           m_pInstance = new CSingleton();    
               return m_pInstance;
   }
};

GetInstance()使用懒惰初始化,也就是说它的返回值是当这个函数首次被访问时被建立的。spa

 上述代码可能存在的问题:操作系统

m_pInstance指向的空间何时释放呢?更严重的问题是,该实例的析构函数何时执行?.net

一个妥善的方法是让这个类本身知道在合适的时候把本身删除,或者说把删除本身的操做挂在操做系统中的某个合适的点上,使其在恰当的时候被自动执行。
咱们知道,程序在结束的时候,系统会自动析构全部的全局变量。事实上,系统也会析构全部的类的静态成员变量,就像这些静态成员也是全局变量同样。利用这个特征,咱们能够在单例类中定义一个静态成员变量,而它的惟一工做就是在析构函数中删除单例类的实例
设计

class CSingleton
{private:
   CSingleton()
   {
   }    
   static CSingleton *m_pInstance;  
    class CGarbo   //它的惟一工做就是在析构函数中删除CSingleton的实例  
      {    
      public:      
       ~CGarbo()
       {        
          if(CSingleton::m_pInstance)
               delete CSingleton::m_pInstance;
       }
   };    
   static CGarbo Garbo;  //定义一个静态成员变量,程序结束时,系统会自动调用它的析构函数public:    static CSingleton * GetInstance()
   {        if(m_pInstance == NULL)  //判断是否第一次调用
           m_pInstance = new CSingleton();        return m_pInstance;
   }
};

类CGarbo被定义为CSingleton的私有内嵌类,以防该类被在其余地方滥用。
程序运行结束时,系统会调用CSingleton的静态成员Garbo的析构函数,该析构函数会删除单例的惟一实例
指针

添加一个类的静态对象,老是让人不太满意,因此有人用以下方法来从新实现单例和解决它相应的问题,代码以下:orm

class CSingleton
{private:
   CSingleton()   //构造函数是私有的    {
   }
   public:
      static CSingleton & GetInstance()
   {        static CSingleton instance;   //局部静态变量
       return instance;
   }
};

使用局部静态变量,很是强大的方法,彻底实现了单例的特性,并且代码量更少,也不用担忧单例销毁的问题。 但使用此种方法也会出现问题,当以下方法使用单例时问题来了, Singleton singleton = Singleton :: GetInstance(); 这么作就出现了一个类拷贝的问题,这就违背了单例的特性。产生这个问题缘由在于:编译器会为类生成一个默认的构造函数,来支持类的拷贝。

最后没有办法,咱们要禁止类拷贝和类赋值,禁止程序员用这种方式来使用单例,函数的代码改成以下:

class CSingleton
{private:
   CSingleton()   //构造函数是私有的    {
   }
   public:  
    static CSingleton * GetInstance()
   {        static CSingleton instance;   //局部静态变量
       return &instance;
   }
};

能够显示的声明类拷贝的构造函数,和重载 = 操做符,新的单例类以下:(个人理解:不将instance设为private static成员变量,是由于不清楚它何时被初始化 )

class CSingleton

{private:    CSingleton()   //构造函数是私有的        {    }    CSingleton(const CSingleton &);    CSingleton & operator = (const CSingleton &);    public:        static CSingleton & GetInstance()    {            static CSingleton instance;   //局部静态变量,相比较指针指向的堆上对象,不用担忧销毁问题        return instance;    }};
相关文章
相关标签/搜索