設計模式之單例模式

2021-10-01 06:33:03 字數 3098 閱讀 8691

單列模式,顧名思義,乙個類只有乙個例項。所以單列模式的特徵為:只有乙個例項,必須提供乙個全域性訪問點(靜態成員方法或靜態靜態成員變數),不可以複製拷貝,如果得到是靜態成員物件指標的位址,必須提供乙個釋放指標的方法。

單列模式,顧名思義,乙個類只有乙個例項。所以單列模式的特徵為:

根據以上描述的特徵,那麼乙個簡單的單例模式就誕生了,如下**所示

template class singleton    static void destroyinstance()        }private:    singleton(){}    ~singlento(){}    singleton(const singleton&);    singleto& operator = (const singleton&);private:    static t* m_pinstance;};template t* singleton::m_pinstance = nullptr;
我們分析下上面**,如果在單執行緒環境下面執行,沒有什麼問題,假設在多執行緒環境中,兩個執行緒同時執行到 m_pinstance == nullptr,此時條件為真,那麼就會建立兩個例項,這不符合單列的特徵,那麼在這裡需要改進,在改進前,我們先用 c++11 實現乙個不可複製的類 noncopyable,以後讓其繼承該類即可

class noncopyable;
然後改進後的單列類如下

#include template class singleton : noncopyable        return m_pinstance;    }    static void destroyinstance()        }private:    static t* m_pinstance;    static std::mutex m_mutex;};template t* singleton::m_pinstance = nullptr;template std::mutex singleton::m_mutex;
我們分析下上面**,解決執行緒安全問題無非就是加鎖,但是如果執行緒很多情況下,每個執行緒都要等拿到鎖的執行緒執行結束後才繼續執行,這樣無疑會導致大量的執行緒阻塞,那麼該如何解決呢,解決辦法就是在鎖之前先判斷是否為 nullptr,於是改進後的**如下:

#include template class singleton : noncopyable        }        return m_pinstance;    }    static void destroyinstance()            }    }private:    static t* m_pinstance;    static std::mutex m_mutex;};template t* singleton::m_pinstance = nullptr;template std::mutex singleton::m_mutex;
繼續分析上面的**,其實這就是所謂的雙檢鎖機制。但是請注意,如果資料量很大的情況,加鎖釋放鎖本來就是耗時的操作,所以在大資料情況下,這種雙檢鎖機制的單列模式效能就顯得堪憂了,所以我們應該避免加鎖操作,於是就出現了另外一種單列模式

template class singleton : noncpyableprivate:    static t* m_pinstance;};template t* singleton::m_pinstance = new t();
繼續分析上面**,巧妙的使用了靜態成員初始化的特性,靜態成員初始化是在程式進入主函式之前,主線程以單執行緒的方式完成了初始化操作,所以很好的解決了執行緒安全問題。但是沒有提供乙個銷毀靜態例項的方法。於是我們可以考慮返回靜態成員物件的位址,然後利用物件的自動銷毀功能來做釋放操作,於改進後的**如下:

template class singleton : noncopyableprivate:    static t m_instance;};template t singleton::m_instance;
這樣的實現應該算是比較好了,但是還有比這更好的完美方法,利用 linux 的 pthreadonce 和 c++11 的 std::callonce

template class singleton : noncopyable    static void destroyinstance()    private:    static t* m_pinstance;    static std::once_flag m_flag;    //static pthread_once_t m_ponce;    static void init()    };//template //pthread_once_t singleton::m_ponce = pthread_once_init;template t* singleton::m_pinstance = nullptr;
另外放乙個超級大招,利用 c++11 的可變模板引數,放乙個萬能的單列模式

template class singleton : noncopyable    static void destroyinstance()    private:    static t* m_pinstance;    static std::once_flag = m_flag;    template static void init(args&&.. args)    };template t* singleton::m_pinstance = nullptr;template std::once_flag singleton::m_flag;
好了,單列模式就分析到這裡了,最後一種是萬金油。上乙個測試**吧

#include #include "singleton4.hpp"struct a    ~a()        int num;    void add(int n)        int getnum()    };struct b    int get()    };int main()
由於本人水平有限,若有錯誤,歡迎指出,謝謝!

閱讀全文:

設計模式之單例模式

前一段時間買了一本秦小波寫的 設計模式之禪 網上對這書的評價很高。現在還沒有看很多,但是有些地方頗有感觸,也並不是所有的地方都能看懂,但是會慢慢研究的。自己對於設計模式的感覺就是乙個字 牛!感覺會23種設計模式並且會熟練運用的人,真的就是大師級的牛人了,設計模式是乙個專案主管或者架構師一定要會的東西...

設計模式之單例模式

package com.xie.singleton public class singleton 提供乙個共有的靜態的入口方法 public static singleton getinstance 懶漢式 延遲載入 提供乙個私有的靜態的成員變數,但不做初始化 private static sing...

設計模式之 單例模式

單例模式 singleton 保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點。單例模式 單件模式 使用方法返回唯一的例項 public class singleton private static singleton instance public static singleton geti...