Singleton Template



  • Ich versuche folgenden Code zu implementieren:

    template <typename C>
     class Singleton
     {
     public:
        static C* instance ()
        {
           if (!_instance)
              _instance = new C ();
           return _instance;
        }
        virtual
        ~Singleton ()
        {
           _instance = 0;
        }
     private:
        static C* _instance;
    protected:
        Singleton () { }
     };
     template <typename C> C* Singleton <C>::_instance = 0;
    
    /* Verwendung */
     class Test : public Singleton <Test>
     {
     friend class Singleton <Test>;
     public:
        ~Test () { };
        static Test* instance ()
        {
           return Singleton <Test>::instance ();
        }
        void xyz () { }
     protected:
        Test () : Singleton <Test> () { }
     };
     Test::instance ()->xyz ();
    

    Dabei frage ich mich aber warum der Konstruktor von Test eliminiert wird, bzw warum der Konstruktor von Singleton aufgerufen wird:

    protected:
        Test () : Singleton <Test> () { }
    

    Matthias



  • Dabei frage ich mich aber warum der Konstruktor von Test eliminiert wird, bzw warum der Konstruktor von Singleton aufgerufen wird:

    😕
    Wie wird den ein Konstruktor eliminiert?!

    Singleton hatten wir gerade Heute wieder:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-224455.html

    Und ich rate auch dir das Meyers Singleton zu benutzen, anstatt etwas so unhandliches zu basteln..



  • Ich habe den Code übrigens hierher:
    http://de.wikibooks.org/wiki/C++-Programmierung:_Entwurfsmuster:_Singleton

    Du meinst das hier?

    class Singleton {
        public:
        static Singleton& Instance() {
          static Singleton theSingleton;
          return theSingleton;
        }
        /* more (non-static) functions here */
        private:
        Singleton(); // ctor hidden
        Singleton(Singleton const&); // copy ctor hidden
        Singleton& operator=(Singleton const&); // assign op. hidden
        ~Singleton(); // dtor hidden
        };
    

    Das ist dann zwar nicht mehr in einem Template aber wenigstes einfach gehalten.

    Kann ich dabei eigentlich noch bestimmen wann die Klasse konstruiert wird, und kann ich sie bei bedarf auch dekonstruieren? Denn das wird hier ja explizit verboten.



  • pospiech schrieb:

    Kann ich dabei eigentlich noch bestimmen wann die Klasse konstruiert wird, und kann ich sie bei bedarf auch dekonstruieren? Denn das wird hier ja explizit verboten.

    Die Konstruktion wird, wie bei Deiner ersten Variante auch, beim ersten Aufruf von getInstace() durchgeführt. Dafür gibt es auch ein Idiom, dass heisst "Construct on first use".
    Die Zerstörung des Objekts hingegen passiert irgendwann wärend Dein Programm beendet wird. Wann genau, das lässt sich nicht beeinflussen. Dafür gibt es aber andere Singleton Varianten, die leider auch ein wenig komplizierter werden.
    Es gibt z.B. Singletons mit festlegbarer Zerstörungspriorität (ich meine, dass nennt sich Longevity-Singleton). Andere Singletons werden zwar zerstört, sollten sie aber nach der Zerstörung nochmal benötigt werden (z.B. weil ein anderes Singleton, welches später zerstört wird es nochmal braucht), werden sie wieder neu erzeugt und dann wieder zerstört usw. (Stichwort: Phönix Singleton).

    Wenn man es soch macht, wie in Deiner ersten Version, braucht man sich um sowas nicht zu kümmern, da die Objekte bestehen bleiben, bis das Betriebssystem sie wegräumt. Das setzt natürlich voraus, dass Du ein Betriebssystem hast, dass sowas auch wirklich macht...



  • Tachyon schrieb:

    Wenn man es soch macht, wie in Deiner ersten Version, braucht man sich um sowas nicht zu kümmern, da die Objekte bestehen bleiben, bis das Betriebssystem sie wegräumt. Das setzt natürlich voraus, dass Du ein Betriebssystem hast, dass sowas auch wirklich macht...

    Oder man überlässt es mit einer "Quit-Funktion" dem User des Singletons das aufräumen, was aber nicht unbedingt sehr elegant ist.



  • Tachyon schrieb:

    Wenn man es soch macht, wie in Deiner ersten Version, braucht man sich um sowas nicht zu kümmern, da die Objekte bestehen bleiben, bis das Betriebssystem sie wegräumt. Das setzt natürlich voraus, dass Du ein Betriebssystem hast, dass sowas auch wirklich macht...

    Ich verstehe nur Bahnhof.
    Natürlich möchte ich das die Objekte beim Programmende aus dem Speicher entfernt werden.

    Warum sollte das bei meinem Template Beispiel nicht passieren?



  • pospiech schrieb:

    Ich verstehe nur Bahnhof.
    Natürlich möchte ich das die Objekte beim Programmende aus dem Speicher entfernt werden.

    Warum sollte das bei meinem Template Beispiel nicht passieren?

    Ja. Du möchtest es, aber du tust es nicht. Ein new ohne ein delete gibt dir ein Speicherleck und das OS muss aufräumen.

    btw:
    Warum bist du so erpicht auf einen Templateansatz? - Das eine hat mit dem anderen rein gar nichts zu tun. - Du kannst auch das Meyers Singleton mit einem Template machen.



  • pospiech schrieb:

    Tachyon schrieb:

    Wenn man es soch macht, wie in Deiner ersten Version, braucht man sich um sowas nicht zu kümmern, da die Objekte bestehen bleiben, bis das Betriebssystem sie wegräumt. Das setzt natürlich voraus, dass Du ein Betriebssystem hast, dass sowas auch wirklich macht...

    Ich verstehe nur Bahnhof.
    Natürlich möchte ich das die Objekte beim Programmende aus dem Speicher entfernt werden.

    Warum sollte das bei meinem Template Beispiel nicht passieren?

    Weil es zu dem new kein delete gibt. Wie gesagt, normalerweise entfernen moderne Betriebsysteme Objekte, die nach dem Programmende noch hängen geblieben sind.
    Es gibt aber durchaus Plattformen, wo es so "fortschrittliches" Speichermanagement nicht gibt. C++ programmierbare digitale Signalprozessoren z.B.


Anmelden zum Antworten