//This file is part of Photon (http://photon.sourceforge.net) //Copyright (C) 2004-2005 James Turk // // Author: // James Turk (jpt2433@rit.edu) // // Version: // $Id: Singleton.hpp,v 1.7 2005/03/15 18:51:00 cozman Exp $ #ifndef PHOTON_UTIL_SINGLETON_HPP #define PHOTON_UTIL_SINGLETON_HPP #include #include "exceptions.hpp" namespace photon { namespace util { // Class: Singleton // Template class for singleton pattern. Is non-copyable to enforce // correct behavior. // // Defining a Singleton: // (code) // YourClass : public Singleton // { // // class definition // }; // (end) // // Using The Singleton: // (code) // new YourClass; // YourClass& yc(YourClass::getInstance()); // // // use yc // // YourClass::destroy(); // (end) template class Singleton : public boost::noncopyable { public: // Function: initialize // Initialize the instance of the singleton, can be done explicitly if // order of construction matters. Will be done on first call to // getInstance otherwise. static void initialize(); // Function: destroy // Destroy the instance of the singleton, can be done explicitly if order // of destruction matters. Will be done automatically if not done. static void destroy(); // Function: getInstance // Get a reference to the instance of the derived class. static T& getInstance(); protected: Singleton(); virtual ~Singleton(); // allow inheritance private: static T* instance_; }; // template implementation template Singleton::Singleton() { if(instance_ != 0) { throw PreconditionException("Attempt to double-initialize singleton."); } instance_ = static_cast(this); // cast self to type of T* } template Singleton::~Singleton() { } template void Singleton::destroy() { if(instance_ == 0) { throw PreconditionException("Attempt to destroy null singleton."); } if(instance_) { delete instance_; instance_ = 0; } } template T& Singleton::getInstance() { if(instance_ == 0) { throw PreconditionException("Attempt to access null singleton."); } return *instance_; //return dereferenced instance } template T* Singleton::instance_(0); } } #endif //PHOTON_UTIL_SINGLETON_HPP