单例模式2(C++)

来源:互联网 发布:mac地址含有非法字符 编辑:程序博客网 时间:2024/05/21 11:12

除了用静态成员的方法保证单例,也可以用一个类变量记录实例对象指针来保存生成的实例。

 

#ifndef _BATS_SINGLETON_HH_
#define _BATS_SINGLETON_HH_

#include <stdexcept>

namespace jmu3d
{
  /**
   * A template to turn any class into a Singleton. To use it on your class:
   * - Define your class's constructor and assignment operator as private
   * - Your class must have a default constructor
   * - Make the singleton a friend of your class.
   * - If your class needs parameters, overload the Params class, define a constructor accepting a Singleton::Params* and use Singleton<T>::initialize<I>(Params*)
   *
   * Example:
   *   \code
       class MyClass
       {
         friend class Singleton<MyClass>;
         ...
       private:
         MyClass();
         MyClass& operator=(MyClass const& other); // Not Implemented
         ...
       };
       \endcode
   */
  template <typename T>
  class Singleton
  {
  public:
    class Params
    {
      public:
        virtual ~Params() {}
    };
   
    /** Initialize the singleton with a new instance of the given type.
    */
    static void initialize()
    {
      if (s_instance)
        delete s_instance;
      s_instance = new T();
    }

    /** Initialize the singleton with a new instance of the given type with parameters
      * @params parameters to be passed to the classes construction
    */
    static void initialize(Params* params)
    {
      if (s_instance)
        delete s_instance;
      s_instance = new T(params);
    }
   
    /** Initialize the singleton with a new instance of the given derived class type.
      * With this method, it is possible to create different derived class type from
      * same abstract singleton type.
    */
    template <typename I>
    static void initialize()
    {
      if(s_instance)
        delete s_instance;
      s_instance = new I();     
    }
   
    /** Initialize the singleton with a new instance of the given type with parameters
      * With this method, it is possible to create different derived class type from
      * same abstract singleton type.
      * @params parameters to be passed to the classes construction

    */
    template <typename I>
    static void initialize(Params *params)
    {
      if(s_instance)
        delete s_instance;
       
      s_instance = new I(params);
    }

    static bool initialized()
    {
      return s_instance? true : false;
    }
   
    /**
     * Get a reference to the only instance of class \a T
     */
    static T& getInstance() {
      if(s_instance == 0)
        throw std::runtime_error("A Singleton must be initialized before use. Call initialize first.");
       
      return *s_instance;
    }
  private:
    static T* s_instance;
    Singleton();
    ~Singleton();
    Singleton(Singleton const&);
    Singleton& operator=(Singleton const&);
  };
 
  template <typename T>
  T* Singleton<T>::s_instance = 0;
}

#endif

s_instance 指针决定了是否已经有实例,设置成静态的是因为要在静态函数里面调用,设计成私有是因为如果它是公有可能会被改变,这样实例就被破坏了~~

原创粉丝点击