單例模式(C++代碼實現)


1、先來談談什么是單例模式

這個單例模式說白了就一個句話:我是皇帝我獨苗

看看書上的定義:單例模式(Singleton Pattern)Ensure a class has only one instance, and provide a global point of access to it.(確保一個類只有一個實例,而且自行實例化並向整個系統提供這個實例)

使用場景:一個系統要求一個類只有且僅有一個對象,如果出現多個對象就會出現不良反應,可以采用單例模式

     要求生成唯一序列號

     在整個項目需要一個共享訪問點或共享數據

     創建一個對象需要消耗的資源過多,如需要訪問IO和數據庫等資源

     需要大量定義靜態常量和靜態方法(如工具類)的環境,當然也可以直接定義為static

2、實現思路:既然只能有一個實例,那我這個類里的構造函數就不能被隨便調用了,那我就把構造函數寫成私有的,這樣別人就不能調用了,接下來就該考慮我自己這個獨苗該怎么產生了,定義里面說到自行實例化,並且提供給整個系統,那我就用一個static  實例化一個實例,然后返回這個static實例。

3、考慮的問題

一個實例,整個系統使用,那線程同步問題就必須要考慮了。

為了解決這個問題:懶漢模式、餓懶漢模式、Meyers Singleton(目前最推薦的C++單例寫法)

4、代碼實現

//Meyers Singleton(目前最推薦的C++單例寫法)
#include <iostream> using namespace std; class Singleton { public: static Singleton& Instance() { static Singleton theSingleton; return theSingleton; } void doSomeThong(); private: Singleton(); ~Singleton(); }; Singleton::Singleton() { } Singleton::~Singleton() { } void Singleton::doSomeThong() { cout << "單例類" << endl; cout << "C++最推薦的單例類寫法" << endl; } int main() { Singleton::Instance().doSomeThong(); return 0; }
//懶漢模式:顧名思義,是一種典型的拖延(lazy)策略。當第一次要用單例類的時候,再產生實例
#include <iostream>

using namespace std;

class Singleton
{
public:
    ~Singleton();
    //提供單例類的訪問方法
    static Singleton* getInstance();
    //提供刪除方法
    static void deleteInstance();
    void doSomething();
protected:
    Singleton();//構造方法定義為protect
    static Singleton* theSingleton; //單例類對象指針

};

Singleton* Singleton::theSingleton = nullptr;//講我們的單例對象指針初始化空

Singleton::Singleton()
{
}

Singleton::~Singleton()
{
}

Singleton* Singleton::getInstance()
{
    if (!theSingleton)
        theSingleton = new Singleton();
    return theSingleton;
}

void Singleton::deleteInstance()
{
    if (theSingleton) {
        delete theSingleton;
        theSingleton = nullptr;
    }
}

void Singleton::doSomething()
{
    cout << "懶漢模式" << "\n" << "單例模式" << endl;
}

int main()
{
    Singleton::getInstance()->doSomething();
    return 0;
}

 看這圖很顯然Singleton成為了一個單例類,但在這一塊我沒有解決線程安全問題,這個需要用到多線程的鎖機制

//餓漢模式
//餓漢模式與懶漢模式相反,是程序一開始就生成唯一實例。這樣就不用檢查是否存在實例,而且也無需考慮產生實例時的線程安全。

#include <iostream>

using namespace std;

class Singleton {
public:
    ~Singleton();
    //提供單例對象訪問
    static Singleton& getInstance();
    void doSomething();
protected:
    //構造函數聲明為 保護方法
    Singleton();
    //單例對象指針
    static Singleton theSingleton;
};

//提供單例類對象訪問
Singleton& Singleton::getInstance() {
    return theSingleton;
}

void Singleton::doSomething()
{
    cout << "餓懶漢模式" << "\n" << "單例模式" << endl;
}

Singleton::Singleton()
{
}
Singleton::~Singleton()
{}

int main()
{
    Singleton::getInstance().doSomething();
    return 0;
}
//很不負責的把這段代碼放在這

5、優點

    ①由於單例模式在內存中只有一個實例,減少了內存開支,特別是一個對象需要頻繁創建銷毀時。

    ②減少系統性能開銷

    ③避免對資源的多重占用

    ④單例模式可以在系統設置全局訪問點,優化和共享資源訪問

6、缺點

     ①單例模式一般沒有接口,很難擴展,擴展基本必須修改源代碼

    ②對測試不友好,需要解決在並發中的問題

    ③單例模式與單一職責原則有沖突

參考書籍《設計模式之禪》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM