設計模式之單例模式實現(C++)
阿新 • • 發佈:2018-04-07
pan sin ace pen bsp ati one delet friend
#ifndef SINGLETON_H #define SINGLETON_H #include <cassert> #include <memory> #include <mutex> #define DECLARE_SINGLETON_CLASS(T) friend Singleton<T> template <typename T> class Singleton { public: using PT = std::shared_ptr<T>; Singleton() = delete;~Singleton() = delete; public: template <typename... Args> static PT getInstance(Args&&... args) { // std::call_once(m_flag, create, std::forward<Args>(args)...); // error: no matching function for call call_once... <unresolved overloaded function type>// couldn‘t deduce template parameter ‘_Callable‘ // why ? std::call_once(m_flag, [&]() { create(std::forward<Args>(args)...); }); assert(m_instance); return m_instance; } private: template <typename... Args> static void create(Args&&... args) { m_instance= std::shared_ptr<T>{new T(std::forward<Args>(args)...), destroy}; } static void destroy(T* t) { delete t; } private: static std::once_flag m_flag; static PT m_instance; }; template <typename T> std::once_flag Singleton<T>::m_flag; template <typename T> typename Singleton<T>::PT Singleton<T>::m_instance{}; #endif // SINGLETON_H
#include "Singleton.h" #include <iostream> #include <string> using namespace std; #define print() cout << "[" << __func__ << ":" << __LINE__ << "]" #define print_position() print() << endl #define print_class() print() << " " << typeid(*this).name() << " " #if 1 class Bundle { public: Bundle() { print_class() << "construct" << endl; } ~Bundle() { print_class() << "destruct" << endl; } Bundle(const Bundle& ) { print_class() << "copy construct" << endl; } Bundle(Bundle&&) { print_class() << "move construct" << endl; } Bundle& operator=(Bundle&) { print_class() << "copy operator assign" << endl; return *this; } Bundle& operator=(Bundle&&) { print_class() << "move operator assign" << endl; return *this; } }; class SingleInstanceKlass { DECLARE_SINGLETON_CLASS(SingleInstanceKlass); private: SingleInstanceKlass() { print_class() << "default construct" << endl; } SingleInstanceKlass(int) { print_class() << "int construct" << endl; } SingleInstanceKlass(const string&) { print_class() << "string construct" << endl; } SingleInstanceKlass(const Bundle&) { print_class() << "Bundle construct" << endl; } ~SingleInstanceKlass() { print_class() << "destruct" << endl; } public: void run() { print_position(); } }; template <typename... Args> void unused(Args...) { } void onExit() { print_position(); } int main(int argc, char *argv[]) { unused(argc, argv); atexit(onExit); print_position(); { Singleton<SingleInstanceKlass>::getInstance(Bundle{}); Singleton<SingleInstanceKlass>::getInstance(3.); Singleton<SingleInstanceKlass>::getInstance(0); Singleton<SingleInstanceKlass>::getInstance("")->run(); } print_position(); return 0; } #endif
設計模式之單例模式實現(C++)