Singleton als Basisklasse



  • Kann ich das irgendwie über auto_ptr regeln???
    Hab das so versucht...

    template<class T> auto_ptr<T>g_apInstance(CSingletonPattern<T>::m_pInstance);
    

    Geht aber nicht...



  • LOLig, das hab ich mir nicht erwartet, gleich soviel Kritik *lol*
    Seht mal zu 1. Jungs. Sonst hätt ich das nie erwähnt 😉

    btw muss Singleton den Konstruktor private definieren, da der Konstruktor von SingletonPattern protected ist und er ihn sonst default- public machen würde



  • Hupsi, Denkfehler, aber ich weiß noch nicht welcher...



  • @MaSTaH
    zeig mal mehr code



  • // Implementierung des Singleton-Patterns
        template <class T> class CSingletonPattern
        {
        private:
            static T* m_pInstance; 
            const CSingletonPattern<T>& operator = (const CSingletonPattern<T>&);
            CSingletonPattern(const CSingletonPattern<T>&);
            ~CSingletonPattern() {}
    
        protected:
            CSingletonPattern(){}
    
        public:
            static T* getInstance() {
                return m_pInstance;
            }
        };
        template<class T> T* CSingletonPattern<T>::m_pInstance = new T;
        template<class T> std::auto_ptr<T>g_apInstance(CSingletonPattern<T>::m_pInstance);
    

    Irgendwas ist da falsch in der auto_ptr-Zeile, komme aber nicht dahinter 😕



  • Mist, doch kein Denkfehler...
    Ich mag langsam meine eigene Idee nicht mehr...

    @MaSTaH: ich hab eher an so was gedacht, um keine unfertigen Objekte zu kriegen:

    template <class T> 
    class AutoHandle {
        auto_ptr<T> object;
    
    public:
        AutoHandle () : object(new T) {}
    
        operator T * () const { return object.get(); }
    };
    
    template <class T>
    class SingletonPattern {
        static AutoHandle<T> Single; 
    
        const SingletonPattern<T> &operator = (const SingletonPattern<T> &);
        SingletonPattern (const SingletonPattern<T> &);
    
    protected:
        SingletonPattern () {}
        virtual ~SingletonPattern () {}
    
    public:
        static T *getInstance () { return Single; }
    };
    
    template <class T>
    AutoHandle<T> SingletonPattern<T>::Single;
    
    class Singleton : public SingletonPattern<Singleton> {
        friend class AutoHandle<Singleton>;
    
        int x;
        Singleton () {}
    
    public:
    
        int getX () const { return x; }
        void setX (int x_) { x = x_; }
    };
    

    wäh pfui, vergebt mir, falls ich da fehler gemacht hab, ich mag den Code langsam echt nicht mehr...



  • dann muss du schon so

    // Implementierung des Singleton-Patterns
        template <class T> class CSingletonPattern
        {
        private:
            static std::auto_ptr<T> m_pInstance; 
            const CSingletonPattern<T>& operator = (const CSingletonPattern<T>&);
            CSingletonPattern(const CSingletonPattern<T>&);
            ~CSingletonPattern() {}
    
        protected:
            CSingletonPattern(){}
    
        public:
            static T* getInstance() {
                return &*m_pInstance;
            }
        };
        template<class T> std::auto_ptr<T> CSingletonPattern<T>::m_pInstance( new T );
    

    aber ich finde ein Meyers-Singleton besser http://fara.cs.uni-potsdam.de/~kaufmann/?page=GenCppFaqs&faq=Singleton#Answ

    template <class T> 
        class CSingletonPattern
        {
        private:
            const CSingletonPattern<T>& operator = (const CSingletonPattern<T>&);
            CSingletonPattern(const CSingletonPattern<T>&);
            ~CSingletonPattern() {}
    
        protected:
            CSingletonPattern(){}
    
        public:
            static T& getInstance() 
            {
                static T instanz;
                return instanz;
            }
        };
    


  • Das Meyers-Singleton ist ja schön pragmatisch einfach, aber hat halt eine mächtige Macke, die seinen praktischen Einsatz in größeren Projekten erheblich einschränkt: nicht thread-sicher.

    Man kann das zwar umgehen, indem man die Singletons erstmalig alle mit Dummy-Aufrufen ::instance() holt um sie zu erzeugen, bevor man seine Threads anlegt. Das wiederläuft aber etwas den Gedanken, daß ein Singleton ja nur konstruiert werden soll, wenn es auch mind. einmal verwendet wird.

    Weiterhin ist die Abbau-Reihenfolge kritisch, läßt sich kaum kontrollieren.

    Siehe dazu:
    http://www.c-plusplus.net/titelanzeige.php?ISBN=0201432935

    (Sorry, Layout ist noch nicht fertig!)



  • Gibt es auch eine "perfekte" Implementation die keine Macken hat?



  • In dem genannten Buch (zu schade, daß es die dt. Version nicht mehr gibt... 😞 ) ist eine Implementation enthalten... Will man die Sachen wie Templateschablone, Threadsicherheit und definierte Abbaureihenfolgen alle erfüllt haben, wird aus diesem eigentlich primitivsten aller Design-Pattern eine richtige Monsterimplementation... z.B. Destruktion mit Hilfe von atexit und ähnlichem.

    Es gibt noch eine Implementation in der Bibliothek "ACE", Suchbegriffe dazu sind "Double-Checked-Locking-Pattern", "Vlissides", "Pattern Hatching April 1996".



  • Marc++us der fragt beim Aufruf der Seite nach einem User/PW für php/dba Access.



  • in den buch modern c++ desing gibt ein template was das können sollte, die lib (loki) zum buch gibt kostenlos online zum downloaden



  • Ich bin der Meinung, dass man sich vorher überlegen sollte, ob man vielleicht nicht doch etwas anderes als ein Singleton will: eine Instanz der Klasse, die überall diesselbe sein soll (sowas wie global)
    Dann reichte nämlich das:

    template <class T>
    class SingletonPattern : public T {
        static SingletonPattern<T> *single;
        SingletonPattern () {}
        SingletonPattern (const SingletonPattern &);
        const SingletonPattern &operator = (const SingletonPattern &);
    
    public:
        static T &getInstance () { return *single; }
    };
    template <class T> SingletonPattern<T> *SingletonPattern<T>::single = new SingletonPattern<T>;
    
    class Klasse {
        int x;
    
    public:
        int getX () const { return x; }
        void setX (int x_) { x = x_; }
    };
    
    int main () {
        {
            Klasse &s = SingletonPattern<Klasse>::getInstance();
            cout << s.getX () << endl;
            s.setX (10);
        }
    
        {
            Klasse &s = SingletonPattern<Klasse>::getInstance();
            cout << s.getX () << endl;
        }
        return 0;
    }
    

    Der Begriff SingletonPattern ist vielleicht irreführend, aber ich wollte die Namen nicht neu schreiben. Ein Singleton ist für mich ein Verbot für den Benutzer, mehrere Instanzen zu erstellen (...)
    Aber meistens/oft braucht man eben so etwas, wie oben beschrieben



  • Ja, das Problem daran sind nur die MemoryLeaks



  • Verdammt nochmal, ich brauche sowas auch gerade.
    Kennt nicht jemand ein gutes Online-Tutorial für so ein perfektes SingleTon, gut erklärt?



  • Ah, hab auch was Feines gefunden: http://www.informatik.fh-muenchen.de/schieder/seminar-oo-modellieren-ws97-98/f7alpha1.informatik.fh-muenchen.de/ifw94005/singleton.html#Absicht
    Ist zwar ein bißchen mieses C++, aber grundsätzlich wird da viel für ein gutes Singleton zusammengebracht. 🙂

    MfG MAV



  • Will man die Sachen wie Templateschablone, Threadsicherheit und definierte Abbaureihenfolgen alle erfüllt haben, wird aus diesem eigentlich primitivsten aller Design-Pattern eine richtige Monsterimplementation

    Und statt diese Monsterimplementation selbst zu basteln, greift man einfach zu Lokis (Andrei Alexandrescus Bibliothek zu "Modern C++ Design") SingletonHolder. Da kann man sich mit Policies alles fein zusammensetzen.



  • Ich bin ehrlichgesagt kein Fan von fremden Libs.
    Ich muss nicht unbedingt Templates verwenden, aber kann man es nicht irgendwie mit einem void* Pointer und nem' Static Cast machen?

    MfG MAV



  • Wozu überhaupt so eine Basisklasse?
    Ich meine das sind doch letztendlich nur drei Zeilen die aus einer Klasse so ein Singleton machen..

    Das Thread-Problem hab ich neulich gehabt (das war ein Spaß, bis ich irgendwann gemerkt hab wo die Problematik liegt ;)).



  • Original erstellt von Mis2com:
    Ich bin ehrlichgesagt kein Fan von fremden Libs.

    Warum das? 😕 Sowas erspart einem oft viel Arbeit!


Anmelden zum Antworten