单例模式

考察内容:

  • 懒汉
  • 线程安全
  • 资源释放

为何静态成员函数可调用ctor? 静态成员函数和成员函数的区别在于是否有this参数,但由于ctor不存在this参数,故静态成员函数可调用

  1. //基础版本
  2. class Singleton{
  3. protected:
  4. Singleton() = default;
  5. ~Singleton() = default;
  6. public:
  7. static Singleton* get_instance(){
  8. if(_instance==nullptr)
  9. _instance=new Singleton();
  10. return _instance;
  11. }
  12. Singleton(const Singleton& rhs)=delete;
  13. Singleton& operator=(const Singleton&) = delete;
  14. private:
  15. static Singleton* _instance;
  16. }
  17. //定义
  18. Singleton* Singleton::_instance=nullptr;
  19. //线程安全资源安全版本
  20. class Singleton {
  21. using safe_ptr = std::shared_ptr<Singleton>;
  22. protected:
  23. Singleton() = default;
  24. ~Singleton() = default;
  25. public:
  26. static safe_ptr get_instance() {
  27. if (_instance == nullptr) {
  28. std::unique_lock<std::mutex> lk(_mtx);
  29. if (_instance == nullptr) {
  30. //防止当一个进程退出后,释放锁,另一个进程也在等待锁拿到后进入,而多创建一个实例
  31. _instance.reset(new Singleton());
  32. }
  33. }
  34. return _instance;
  35. }
  36. Singleton(const Singleton&) = delete;
  37. Singleton& operator=(const Singleton&) = delete;
  38. private:
  39. static safe_ptr _instance;
  40. static std::mutex _mtx;
  41. };
  42. std::shared_ptr<Singleton> Singleton::_instance = nullptr;
  43. std::mutex Singleton::_mtx;
  44. //线程安全资源安全版本2
  45. class Singleton {
  46. using safe_ptr = std::shared_ptr<Singleton>;
  47. protected:
  48. Singleton() = default;
  49. ~Singleton() = default;
  50. public:
  51. static safe_ptr get_instance() {
  52. std::call_once(_flag, []()
  53. {
  54. _instance.reset(new Singleton());
  55. });
  56. return _instance;
  57. }
  58. Singleton(const Singleton&) = delete;
  59. Singleton& operator=(const Singleton&) = delete;
  60. private:
  61. static safe_ptr _instance;
  62. static std::once_flag _flag;
  63. };
  64. std::shared_ptr<Singleton> Singleton::_instance = nullptr;
  65. std::once_flag Singleton::_flag;
  66. //模板版本
  67. template<class Derived>
  68. class Singleton{
  69. public:
  70. template<class ...Args>
  71. static Derived& get_Instance(const Args& ...args);
  72. protected:
  73. Singleton() =default;
  74. ~Singleton() =default;
  75. private:
  76. static std::shared_ptr<Derived> _Instance;
  77. static std::once_flag _flag;
  78. }
  79. template<class Derived>
  80. template<class ...Args>
  81. static Derived& get_Instance(const Args& ...args){
  82. std::call_once(_flag,[](auto ...args){
  83. _Instance.reset(new Derived(args...))
  84. ,args...});
  85. return *_Instance;
  86. }
  87. template<class Derived>
  88. std::shared_ptr<Derived> Singleton<Derived>::_Instance = nullptr;
  89. template<class Derived>
  90. std::once_flag Singleton<Derived>::_flag;
  91. class A:public Singleton<A>
  92. {
  93. friend class Singleton<derivedA>;
  94. private:
  95. int val;
  96. derived(int v):
  97. val(v){}
  98. public:
  99. constexpr
  100. int get_val() const noexcept { return val; }
  101. }