/****************************************************************************** singleton.h: singleton template Copyright (C) 2012-2016 Wang Bin This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ******************************************************************************/ #ifndef SINGLETON_H #define SINGLETON_H #include #include //harmattan: atexit #include #define USE_EXCEPTION 0 #if USE_EXCEPTION #include // std::string breaks abi #endif #ifdef DEBUG #define DBG(fmt, ...) \ fprintf(stderr, fmt, ##__VA_ARGS__); \ fflush(0); #else #define DBG(...) #endif //DEBUG #define DISABLE_COPY(Class) \ Class(const Class &); \ Class &operator=(const Class &); /* * Used in library, can not be used both in library and outside. so we don't need export it */ template class Singleton { DISABLE_COPY(Singleton) public: typedef T ObjectType; static T& Instance(); protected: Singleton() {} virtual ~Singleton() {} private: static void MakeInstance(); static void DestroySingleton(); static T* pInstance_; static bool destroyed_; }; /*if it is used as dll, template will instanced in dll and exe *, and pInstance_ are 0 for both*/ //TODO: use static Singleton inst; return inst; template T* Singleton::pInstance_ = 0; //Why it will be initialized twice? The order? template bool Singleton::destroyed_ = false; template T &Singleton::Instance() { //DBG("instance = %p\n", pInstance_); if (!pInstance_) { MakeInstance(); } return *pInstance_; } template void Singleton::MakeInstance() { if (!pInstance_) { if (destroyed_) { destroyed_ = false; #if USE_EXCEPTION throw std::logic_error("Dead Reference Detected"); #else DBG("Dead Reference Detected"); exit(1); #endif //QT_NO_EXCEPTIONS } pInstance_ = new T(); DBG("Singleton %p created...\n", pInstance_); std::atexit(&DestroySingleton); } } template void Singleton::DestroySingleton() { DBG("DestroySingleton...\n"); assert(!destroyed_); delete pInstance_; pInstance_ = 0; destroyed_ = true; } #endif // SINGLETON_H