Singleton als Basisklasse



  • Hallo, habe mich heute mal mit Singletons beschäftigt...
    Ist es möglich einmal ein Singleton als Basisklasse zu erstellen und dann immer wenn eine neue Klasse nur einmal instanziert werden soll diese von der Singleton-Basisklasse abzuleiten??? Wenn ja... wie??? Habe jetzt den Umweg, dass ich die GetInstance-Funktion immer in die Ableitung einbinden muss...

    So ist das bei mir...

    class CDerived : public CSingleton
    {
    public:
        void Test(){
            AfxMessageBox("Test");
        }
        static CDerived* GetInstance() {
            return static_cast<CDerived*>(CSingleton::GetInstance()); // @Lars und Shade: Seht ihr den Cast???  :D 
        }
    };
    

    Gibt es irgendeinen Kniff mit dem ich es umgehen kann die GetInstance-Funktion einzubauen??? (Hatte im ersten Moment an Templates gedacht... kam aber auf keinen grünen Zweig)... Wenns nicht geht ist auch nicht schlimm...



  • Jede abgeleitete Klasse hat "in sich" ein eigenes Singleton (?)
    Meiner Meinung nach ist das dann nicht mehr der Sinn der Sache

    Oder:
    Willst du einfach das Pattern vererben? Also dass die abgeleitete Klasse automatisch ein Singelton ist?



  • Außerdem ist der Konstruktor von Singleton ja private
    ich hirnie. damit geht ableiten sowieso nicht! außer du machst ihn protected und dann ist es kein richtiger singleton mehr, ne?!



  • Original erstellt von <Pfui>:
    Willst du einfach das Pattern vererben? Also dass die abgeleitete Klasse automatisch ein Singelton ist?

    Genau das... Dachte mir, dass das irgendwie möglich sein müsste... 😕



  • Original erstellt von <etc>:
    Außerdem ist der Konstruktor von Singleton ja private
    ich hirnie. damit geht ableiten sowieso nicht! außer du machst ihn protected und dann ist es kein richtiger singleton mehr, ne?!

    Warum soll das nicht gehen??? 😕 Der VC++ meckert nicht wenn ich das so mache...



  • Ich versuch es mal... Ich weiß aber nicht, ob es schon so ein Pattern gibt.
    Also, eine Idee, die Form angenommen hat (grad erfunden, also bitte Nachsicht groß schreiben :)) :

    template <class T>
    class SingletonPattern {
    
       static T *Single; 
    
       const SingletonPattern<T> &operator = (const SingletonPattern<T> &);
       SingletonPattern (const SingletonPattern<T> &);
    
    protected:
       SingletonPattern () {}
       virtual ~SingletonPattern () { delete Single; }
    
    public:
       static T *getInstance () { return Single; }
    };
    template <class T>
    T *SingletonPattern<T>::Single = new T;
    
    class Singleton : public SingletonPattern<Singleton> {
        friend class SingletonPattern<Singleton>; //Wichtig!!!
    
        int x;
    protected:
        Singleton () : x(123) {}
    
    public:
        int getX () const { return x; }
        void setX (int x_) { x = x_; }
    };
    
    int main () {
        Singleton &x = *Singleton::getInstance();
        Singleton *y = Singleton::getInstance();
    
        cout << "X: " << x.getX() << endl;
        cout << "Y: " << y->getX() << endl;
    
        x.setX (456);
    
        cout << "X: " << x.getX() << endl;
        cout << "Y: " << y->getX() << endl;
    
        return 0;
    }
    


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


Anmelden zum Antworten