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
