#pragma once /////////////////////////////////////////////////////////////////////// // RepositorySingleton.h - another application of Singleton Pattern // // ver 2 // // Jim Fawcett, CSE776 - Design Patterns, Fall 2017 // /////////////////////////////////////////////////////////////////////// /* * Ver 2 : 13 Sep 2017 * - Abandons, for now, double-check locking optimization. That turned * out to be trickier for C++ than I expected. * - The next version will reintroduce a correct version of double-check * locking (in SingletonBase) if there is enough performance gain * to be worth the added complexity. * http://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11/ */ #include "../RepositoryBase/RepositoryBase.h" #include "../SingletonBase/SingletonBase.h" namespace Singleton { // Utilities::Log log; defined as global object in SingletonBase ///////////////////////////////////////////////////////////////////// // RepositorySingleton class // - Derives publically from both RepositoryBase and SingletonBase // - This class needs some knowledge of how SingletonBase works. // - The important fact is that RepositoryBase doesn't need to know // anything about Singleton behavior. It's in that class where all // the application specific code resides, so we are factoring out // Singleton behavior to make that class focus on its mission. // template class RepositorySingleton : public RepositoryBase, public SingletonBase { public: static RepositorySingleton* Instance() { if (SingletonBase::pInstance == nullptr) { SingletonBase* pBase = SingletonBase::Instance(); log.doLog("\n creating instance of RepositorySingleton"); Lock lock; pRepo = new RepositorySingleton(pBase); } return pRepo; } void Release() { pInstance->Release(); if (refCount == 0) { log.doLog("\n destroying instance of RepositorySingleton"); Lock lock; delete pRepo; pRepo = nullptr; } } private: virtual ~RepositorySingleton() {} RepositorySingleton(SingletonBase* pSB) : SingletonBase(*pSB) { log.doLog("\n created copy of SingletonBase while constructing RepositorySingleton"); } RepositorySingleton() = delete; RepositorySingleton(const RepositorySingleton&) = delete; static RepositorySingleton* pRepo; }; template RepositorySingleton* RepositorySingleton::pRepo = nullptr; }