Singleton als Basisklasse



  • Comeau Compiliert (ich liebe Alliterationen)



  • Gut gemacht! 🙂



  • LOL, man könnte meinen, ich gratuliere mir selbst (Was ein Moderator mit IP Prüfung natürlich verneinen kann!)

    Aber Danke erstmal, ich arbeite noch etwas weiter daran, wenn wer es will und nix dagegen hat.



  • hm naja, hab doch keine Lust mehr. Was mich noch stört ist, dem Konstruktor keine Argumente geben zu können und die Ausnahmeunsicherheit. Würd' ich mit auto_ptr oder einem auto_ptr Wrapper machen. 🙂



  • Keine Selbstgespräche bitte! 🙄



  • du Troll, du!



  • EDIT: war blödsinn

    [ Dieser Beitrag wurde am 10.02.2003 um 19:45 Uhr von MaSTaH editiert. ]



  • Hab das jetzt so gemacht:

    template <class T> class CSingletonPattern
        {
        private:
            static T* m_pInstance; 
            const CSingletonPattern<T>& operator = (const CSingletonPattern<T>&);
            CSingletonPattern(const CSingletonPattern<T>&);
            ~CSingletonPattern() { delete m_pInstance; }
    
        protected:
            CSingletonPattern(){}
    
        public:
            static T* getInstance() {
                return m_pInstance;
            }
        };
        template<class T> T* CSingletonPattern<T>::m_pInstance = new T;
    
        class CSingleton : public CSingletonPattern<CSingleton> {
        public:
            void Test(){ AfxMessageBox("Singleton-Test1"); }
        };
    

    Mein einziges Problem sind jetzt noch MemoryLeaks beim beenden, da ich m_pInstance nicht deleten kann...



    ~CSingletonPattern () { delete m_pInstance; }
    reicht das nicht?

    Beim Beenden ist das sowieso egal, da dein OS (normalerweise) die belegten Ressourcen automatisch wieder freigibt



  • Original erstellt von <?>:
    Beim Beenden ist das sowieso egal, da dein OS (normalerweise) die belegten Ressourcen automatisch wieder freigibt

    solte man sich nie drauf verlassen



  • Original erstellt von <?>:
    2.
    Beim Beenden ist das sowieso egal, da dein OS (normalerweise) die belegten Ressourcen automatisch wieder freigibt

    Gewöhn' Dir sowas nicht an. Ruckzuck wandert mal ein Programmteil vom "Ende" plötzlich ins "Nur-Ende-eines-Bearbeitungszyklus" und die Freude ist groß.



  • 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?


Anmelden zum Antworten