单例模式
考察内容:
- 懒汉
- 线程安全
- 资源释放
为何静态成员函数可调用ctor? 静态成员函数和成员函数的区别在于是否有this参数,但由于ctor不存在this参数,故静态成员函数可调用
//基础版本class Singleton{protected:Singleton() = default;~Singleton() = default;public:static Singleton* get_instance(){if(_instance==nullptr)_instance=new Singleton();return _instance;}Singleton(const Singleton& rhs)=delete;Singleton& operator=(const Singleton&) = delete;private:static Singleton* _instance;}//定义Singleton* Singleton::_instance=nullptr;//线程安全资源安全版本class Singleton {using safe_ptr = std::shared_ptr<Singleton>;protected:Singleton() = default;~Singleton() = default;public:static safe_ptr get_instance() {if (_instance == nullptr) {std::unique_lock<std::mutex> lk(_mtx);if (_instance == nullptr) {//防止当一个进程退出后,释放锁,另一个进程也在等待锁拿到后进入,而多创建一个实例_instance.reset(new Singleton());}}return _instance;}Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;private:static safe_ptr _instance;static std::mutex _mtx;};std::shared_ptr<Singleton> Singleton::_instance = nullptr;std::mutex Singleton::_mtx;//线程安全资源安全版本2class Singleton {using safe_ptr = std::shared_ptr<Singleton>;protected:Singleton() = default;~Singleton() = default;public:static safe_ptr get_instance() {std::call_once(_flag, [](){_instance.reset(new Singleton());});return _instance;}Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;private:static safe_ptr _instance;static std::once_flag _flag;};std::shared_ptr<Singleton> Singleton::_instance = nullptr;std::once_flag Singleton::_flag;//模板版本template<class Derived>class Singleton{public:template<class ...Args>static Derived& get_Instance(const Args& ...args);protected:Singleton() =default;~Singleton() =default;private:static std::shared_ptr<Derived> _Instance;static std::once_flag _flag;}template<class Derived>template<class ...Args>static Derived& get_Instance(const Args& ...args){std::call_once(_flag,[](auto ...args){_Instance.reset(new Derived(args...)),args...});return *_Instance;}template<class Derived>std::shared_ptr<Derived> Singleton<Derived>::_Instance = nullptr;template<class Derived>std::once_flag Singleton<Derived>::_flag;class A:public Singleton<A>{friend class Singleton<derivedA>;private:int val;derived(int v):val(v){}public:constexprint get_val() const noexcept { return val; }}
