單例模式

設計模式--單例模式:
創建一個安全並且高效的Sington很重要。
(1)單例類保證全局只有一個唯一實例對象;
(2)單例類提供獲取這個唯一實例的接口。
下面爲四種創建單例類的方法:

 //單例模式
////////不考慮線程安全的單例類//////////
class Singleton
{
public:

           //獲取唯一對象實例的接口函數
           static Singleton * GetIntance()
          {
                    if (_sIntance == NULL )
                   {
                              if (_sIntance == NULL )
                             {
                                      _sIntance = new Singleton ();
                             }
                   }
                    return _sIntance;
          }

           //刪除實例對象
           static void DelIntance()
          {
                    if (_sIntance)
                   {
                              delete _sIntance;
                             _sIntance = NULL;
                   }
          }

           void Print()
          {
                   cout << _data << endl;

          }

private:
           //構造函數定義爲私有,限制只能在類內創建對象
          Singleton()
                   :_data(0)
          {}

           //防拷貝
          Singleton( const Singleton &);
           Singleton& operator=(const Singleton&);
private:
           static Singleton * _sIntance;//指向實例的指針定義爲靜態私有,定義靜態函數獲取實例對象
           int _data;//單例類裏的數據
};

Singleton* Singleton ::_sIntance = NULL; //靜態成員只能在類外初始化

void TestSingleton()
{
           Singleton::GetIntance()->Print();
           Singleton::DelIntance();
}
 ////////////線程安全的單例模式(懶漢模式)////////////
class Singleton
{
public:
           //獲取唯一對象實例的接口函數
           static Singleton * GetIntance()
          {
                    //使用雙重檢查,提高效率,避免高併發場景下每次獲得實例對象都進行加鎖,浪費資源
                    if (_sIntance == NULL )
                   {
                             std:: lock_guard<std::mutex > lck(_mtx);
                              if (_sIntance == NULL )
                             {
                                       Singleton* tmp = new Singleton();
                                      MemoryBarrier(); //內存柵欄,防止編譯器重排柵欄後的賦值到柵欄之前
                                      _sIntance = tmp;
                             }
                   }
                    return _sIntance;
          }

           //刪除實例對象
           static void DelIntance()
          {
                   std:: lock_guard<std::mutex > lck(_mtx);
                    if (_sIntance)
                   {
                              delete _sIntance;
                             _sIntance = NULL;
                   }
          }

           void Print()
          {
                   cout << _data << endl;

          }


private:
           //構造函數定義爲私有,限制只能在類內創建對象
          Singleton()
                   :_data(0)
          {}
          
           //防拷貝
          Singleton( const Singleton &);
           Singleton& operator=(const Singleton&);

private:
           static mutex _mtx;//保證線程安全的互斥鎖
           static Singleton * _sIntance;//指向實例的指針定義爲靜態私有,定義靜態函數獲取實例對象
           int _data;//單例類裏的數據
};

Singleton* Singleton ::_sIntance = NULL; //靜態成員只能在類外初始化
mutex Singleton::_mtx;

void TestSingleton()
{
           Singleton::GetIntance()->Print();
           Singleton::DelIntance();
}
  /////////////餓漢模式(簡潔,不加鎖)/////////////////////////
class Singleton
{
public:

           //獲取唯一對象實例的接口函數
           static Singleton * GetIntance()
          {
                    static Singleton sIntance;
                    return &sIntance;
          }

           void Print()
          {
                   cout << _data << endl;
          }

private:
           //構造函數定義爲私有,限制只能在類內創建對象
          Singleton()
                   :_data(0)
          {}

           //防拷貝
          Singleton( const Singleton &);
           Singleton& operator=(const Singleton&);
private:
           int _data;//單例類裏的數據
};

void TestSingleton()
{
           Singleton::GetIntance()->Print();
}





////////// /////餓漢模式2////////////////////
class Singleton
{
public:

           //獲取唯一對象實例的接口函數
           static Singleton *GetIntance()
          {
                    assert(_sIntance);
                    return _sIntance;
          }

           //刪除實例對象
           static void DelIntance()
          {
                    if (_sIntance)
                   {
                              delete _sIntance;
                             _sIntance = NULL;
                   }
          }

           void Print()
          {
                   cout << _data << endl;
          }

private:
           //構造函數定義爲私有,限制只能在類內創建對象
          Singleton()
                   :_data(0)
          {}

           //防拷貝
          Singleton( const Singleton &);
           Singleton& operator=(const Singleton&);
private:
           static Singleton * _sIntance;//指向實例的指針定義爲靜態私有,定義靜態函數獲取實例對象
           int _data;//單例類裏的數據
};

Singleton* Singleton ::_sIntance = new Singleton; //靜態成員只能在類外初始化

void TestSingleton()
{
           Singleton::GetIntance()->Print();
           Singleton::DelIntance();
}
 ///////////////使用RAII GC自動回收實例對象的方式///////////
class Singleton
{
public:

           //獲取唯一對象實例的接口函數
           static Singleton * GetIntance()
          {
                    assert(_sIntance);
                    return _sIntance;
          }

           //刪除實例對象
           static void DelIntance()
          {
                    if (_sIntance)
                   {
                              delete _sIntance;
                             _sIntance = NULL;
                   }
          }

           void Print()
          {
                   cout << _data << endl;

          }

           class GC
          {
           public:
                   ~GC()
                   {
                             cout << "DelIntance" << endl;
                             DelIntance();
                   }
          };

private:
           //構造函數定義爲私有,限制只能在類內創建對象
          Singleton()
                   :_data(0)
          {}

           //防拷貝
          Singleton( const Singleton &);
           Singleton& operator=(const Singleton&);
private:
           static Singleton * _sIntance;//指向實例的指針定義爲靜態私有,定義靜態函數獲取實例對象
           int _data;//單例類裏的數據
};

Singleton* Singleton ::_sIntance = new Singleton; //靜態成員只能在類外初始化

//使用RAII,定義全局的GC對象釋放對象實例
Singleton::GC gc;

void TestSingleton()
{
           Singleton::GetIntance()->Print();
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章