C++可繼承的單例基類模板


一、介紹

最近在寫一個項目,其中用到好幾個單例,類本身的設計不是很復雜,但是如果每個都寫一遍單例又覺得有點冗余;所以查資料寫了一個單例基類模板,只要一個類繼承這個基類並且以自身作為模板參數就可以實現一個單例;關於單例本身的介紹在這里不重點介紹,感興趣的可以看一下我的另外一篇博文(https://www.cnblogs.com/sunchaothu/p/10389842.html),寫的非常詳細,把各種單例實現方法總結了一遍,並且給出技術細節分析。

特點:

  • 線程安全,使用 staic local,保證線程安全 (C++11)
  • 可以繼承的模板,更加方便的實現單例

二、代碼

// author: sunchaothu
// brief: a singleton base class offering an easy way to create singleton
#include <iostream>

template<typename T>
class Singleton{
public:
    static T& get_instance() noexcept(std::is_nothrow_constructible<T>::value){
        static T instance;
        return instance;
    }
    virtual ~Singleton() noexcept{
        std::cout<<"destructor called!"<<std::endl;
    }
    Singleton(const Singleton&)=delete;
    Singleton& operator =(const Singleton&)=delete;
protected:
    Singleton(){
        std::cout<<"constructor called!"<<std::endl;
    }

};
/********************************************/
// Example:
// 1.friend class declaration is requiered!
// 2.constructor should be private


class DerivedSingle:public Singleton<DerivedSingle>{
   // !!!! attention!!!
   // needs to be friend in order to
   // access the private constructor/destructor
   friend class Singleton<DerivedSingle>;
public:
   DerivedSingle(const DerivedSingle&)=delete;
   DerivedSingle& operator =(const DerivedSingle&)= delete;
private:
   DerivedSingle()=default;
};

int main(int argc, char* argv[]){
    DerivedSingle& instance1 = DerivedSingle::get_instance();
    DerivedSingle& instance2 = DerivedSingle::get_instance();
    return 0;
}

以上代碼放在了 我的github中: https://github.com/sunchaothu/AdvancedCpp/tree/master/singleton

三、關鍵處

  • 子類需要把自己作為模板參數,如 class DerivedSingle:public Singleton<DerivedSingle>;
    這里用到的是CRTP(Curiously recurring template pattern) 奇異循環模板模式
  • 在子類中需要把基類 Singleton 聲明為友元;這樣才能訪問私有構造函數(這個鏈接里還提供了不需要聲明為友元的實現)
  • 這個使用了局部靜態變量保證了線程安全,成為 Magic Static。

四、使用限制

繼承了這個類的代碼不可以作為基類再被繼承。

五、參考資料

以上代碼參考了以下鏈接;如果有紕漏之處,還請指正,以免誤人子弟!

  1. https://stackoverflow.com/questions/34519073/inherit-singleton?r=SearchResults
  2. https://www.cnblogs.com/lidabo/p/3949226.html


免責聲明!

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



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