C++單例模式實現(xiàn)(線程安全&支持多參數(shù)構(gòu)造)

C++單例模式實現(xiàn)(線程安全&支持多參數(shù)構(gòu)造)

線程安全版本

#include <<mutex>>

template <class T> class ThreadSafeSingleton {
public:
  static T& get() {
    std::call_once(ThreadSafeSingleton<T>::create_once_, &ThreadSafeSingleton<T>::Create);
    return *ThreadSafeSingleton<T>::instance_;
  }
protected:
  static void Create() { instance_ = new T(); }
  static std::once_flag create_once_;
  static T* instance_;
};

template <class T> std::once_flag ThreadSafeSingleton<T>::create_once_;

template <class T> T* ThreadSafeSingleton<T>::instance_ = nullptr;

支持多參數(shù)版本的單例類

#include <iostream>
#include <mutex>
#include <cassert>

template<class T>
class ThreadSafeSingleton {

public:
  template<typename...Args>
  static T& Getinstance(Args&&... args) {
    std::call_once(ThreadSafeSingleton<T>::_call_once_flag,
                   std::forward<void(Args&&...)>(&ThreadSafeSingleton<T>::init),
                   std::forward<Args>(args)...);
    return *ThreadSafeSingleton<T>::m_instance;
  }

private:
  ThreadSafeSingleton() = default;
  ~ThreadSafeSingleton() {
    delete ThreadSafeSingleton<T>::m_instance;
    ThreadSafeSingleton<T>::m_instance = nullptr;
  }
  ThreadSafeSingleton(const ThreadSafeSingleton& o) = delete;
  ThreadSafeSingleton& operator=(const ThreadSafeSingleton& o) = delete;
  
  template<typename...Args>
  static void init(Args&&...args) {
    m_instance =  new T(std::forward<Args>(args)...);
  }

private:
  static std::once_flag _call_once_flag;
  static T* m_instance;
};

template<class T> T* ThreadSafeSingleton<T>::m_instance = nullptr;
template<class T> std::once_flag ThreadSafeSingleton<T>::_call_once_flag;

遇到問題點(diǎn):

  • std::call_once中模板傳參時候需要注意點(diǎn): 第二個參數(shù)為函數(shù)參數(shù)

  • std::forward<函數(shù)類型>(具體值)

std::forward<void(Args&&...)>(&ThreadSafeSingleton<T>::init),

最后調(diào)用:

  std::call_once(ThreadSafeSingleton<T>::_call_once_flag,

?          std::forward<void(Args&&...)>(&ThreadSafeSingleton<T>::init),

?          std::forward<Args>(args)...);

測試代碼:

class TestSingleton1 {
public:
  TestSingleton1(const std::string&){ std::cout << "lvalue" << std::endl;}
  TestSingleton1(std::string&&){ std::cout << "rvalue" << std::endl;}
  ~TestSingleton1() = default;
  void testFunc() {
    std::cout << "test function 1" << "\n";
  }
};

class TestSingleton2 {
public:
  TestSingleton2(const std::string&){ std::cout << "lvalue" << std::endl;}
  TestSingleton2(std::string&&){ std::cout << "rvalue" << std::endl;}
  ~TestSingleton2() = default;
  void testFunc() {
    std::cout << "test function 2" << "\n";
  }
};
class TestSingleton3 {
public:
  TestSingleton3(const std::string&,int i,double k){ std::cout << "lvalue" << std::endl;}
  ~TestSingleton3() = default;
  void testFunc() {
    std::cout << "test function 3" << "\n";
  }
};



int main(int argc, char **argv) {
    std::string str = "bb";
    ThreadSafeSingleton<TestSingleton1>::Getinstance(str).testFunc();
 ThreadSafeSingleton<TestSingleton2>::Getinstance(std::move(std::string("xxxx"))).testFunc();
    ThreadSafeSingleton<TestSingleton3>::Getinstance("yyyy",1,2.0).testFunc();
    return 0
}

本文代碼參考

《深入應(yīng)用C++11》

本文由博客群發(fā)一文多發(fā)等運(yùn)營工具平臺 OpenWrite 發(fā)布

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本文根據(jù)眾多互聯(lián)網(wǎng)博客內(nèi)容整理后形成,引用內(nèi)容的版權(quán)歸原始作者所有,僅限于學(xué)習(xí)研究使用,不得用于任何商業(yè)用途。 互...
    深紅的眼眸閱讀 1,235評論 0 0
  • 手把手教你在c++中實現(xiàn)python *args的功能 本文大概先通過鋪墊3-4節(jié)的預(yù)備知識便于讀者的理解,如有不...
    WOWSCpp閱讀 1,476評論 0 2
  • 最近是恰好寫了一些c++11多線程有關(guān)的東西,就寫一下筆記留著以后自己忘記回來看吧,也不是專門寫給讀者看的,我就想...
    編程小世界閱讀 2,760評論 1 2
  • 接著上節(jié) atomic,本節(jié)主要介紹condition_varible的內(nèi)容,練習(xí)代碼地址。本文參考http://...
    jorion閱讀 8,652評論 0 7
  • 比特幣自進(jìn)入7月以來,受比特幣ETF預(yù)期推出的消息影響,走出了一波波瀾壯闊的行情,比特幣價格在不到一個月的時間里從...
    易涵在哪閱讀 224評論 0 0

友情鏈接更多精彩內(nèi)容