ne frage zum singleton



  • hio!
    ich wollte mal gerne wissen, weshalb der pointer in der die instanz gespeichert wird und die beiden memberfunktionen static sind?
    folgendes singleton:

    #ifndef TSINGLETON
    #define TSINGLETON
    
    template <class type>
    class T_singleton
    {
        protected:
    
            // static membervars
            static type *m_p_singleton;     // statisches objekt
    
        public:
    
            // memberfuncs
    
            // dtor
            virtual ~T_singleton ()
            {
            }
    
            // static memberfuncs
    
            // get
            // aufgabe: wenn nötig, statisches objekt erzeugen
            // und Zeiger darauf zurückgeben
            inline static type* get ()
            {
                // existiert schon eine instanz?
                if (!m_p_singleton)
                {
                    m_p_singleton = new type;      // nein, dann neue instanz erzeugen
                }
    
                // zeiger auf die instanz zurückgeben
                return m_p_singleton;
            } // get ende
    
            // del
            // aufgabe: statisches objekt freigeben
            static void del ()
            {
                // gab es eine instanz?
                if (m_p_singleton)
                {
                    delete m_p_singleton;       // ja, dann freigeben
                    m_p_singleton = NULL;       // und zeiger auf NULL setzen
                }
            } // del
    };
    
    // globals
    // declare (define) static membervars
    template <class type>
    type* T_singleton<type> :: m_p_singleton = 0;
    
    #endif
    


  • Von einem Singleton soll nur eine Instanz existieren. Diese Instanz muss verwaltet werden und von überall zugreifbar sein. Da nur eine Instanz existieren soll, wird die Instanzvariable statisch gemacht und die Zugriffsmethoden auch (dadurch "spart" man sich eine globale Variable, die den Zeiger hält).

    Normalerweise stellt man zumindest noch sicher, dass man nicht zwei Instanzen von dem Singleton erzeugen kann (bei dem Template-Code von Dir hindert der Compiler Dich nicht dran).

    class X {
    };
    
    typedef T_Singleton<X> SingleX;
    
    void f() 
    {
      X* x( SingleX::get());
      // mach was mit x
    }
    


  • EDIT: Bloedsinn.



  • und das del() ist auch etwas überflüssig



  • net schrieb:

    und das del() ist auch etwas überflüssig

    Nicht wenn Du es im Destruktor aufrufst. Damit kann man mit noch einem kleinen Trick feststellen, dass das Singleton schon tot ist (Zerstörungsreihenfolge von statischen Objekten).

    Hier mal noch eine Singleton-Implementierung, die mir sehr gut gefällt und sich dem bereits toten Singleton annimmt. Ist quasi übernommen aus "Modern C++ Design".

    // Singleton.h
    class Singleton
    {
    public:
      Singleton& Instance()
      {
        if (!pInstance_)
        {
          // Check for dead reference
          if (destroyed_)
          {
            OnDeadReference();
          }
          else
          {
            // First call—initialize
            Create();
          }
        }
        return pInstance_;
      }
    private:
      // Create a new Singleton and store a
      // pointer to it in pInstance_
      static void Create();
      {
        // Task: initialize pInstance_
        static Singleton theInstance;
        pInstance_ = &theInstance;
      }
      // Gets called if dead reference detected
      static void OnDeadReference()
      {
        throw std::runtime_error("Stocherst Du gern in Leichen? :D");
      }
      virtual ~Singleton()
      {
        pInstance_ = 0;
        destroyed_ = true;
      }
      // Data
      Singleton pInstance_;
      bool destroyed_;
      ... disabled 'tors/operator= ...
    };
    
    // Singleton.cpp
    Singleton* Singleton::pInstance_ = 0;
    bool Singleton::destroyed_ = false;
    


  • 7H3 N4C3R schrieb:

    net schrieb:

    und das del() ist auch etwas überflüssig

    Nicht wenn Du es im Destruktor aufrufst. Damit kann man mit noch einem kleinen Trick feststellen, dass das Singleton schon tot ist (Zerstörungsreihenfolge von statischen Objekten).

    dieses objekt ist aber nicht statisch weils auf'n heap gepackt wird. mit diesem del () kann man's beseitigen, aber ich denke zu einem singleton gehört nicht nur dessen einmaligkeit sondern auch das es ständig verfügbar ist.



  • Der Zeiger ist aber statisch in dem Beispiel, was auch ausreicht. Der Trick ist eben, das statische Objekt in ne Createfunktion zu packen und den Zeiger an das getInstance rauszureichen. Hab meinen obigen Post noch editiert 🙂


Anmelden zum Antworten