singelton und destruktor?



  • Xantus_notloggedin schrieb:

    Treb schrieb:

    OS räumt auf

    da wär ich mir nicht so sicher...

    Windows macht das z.B.

    Xantus_notloggedin schrieb:

    @BorisDieKlinge:

    //...
    public:
      ~Singleton() {
          if(instanz) {
              delete instanz;
              instanz = 0;
          }
       }
    //...
    

    Sehr clever, ja... Nur wird der Destruktor halt nicht aufgerufen.
    Eine Lösung wäre folgende:

    class Singleton
    {
    public:
       static Singleton* exemplar()
       {
    	   if( instanz == 0 )
    	   {
    		instanz = new Singleton();
    		atexit( &Singleton::destroy );
    	   }
    	   return instanz;
       }
    
       static void destroy()
       {
    	delete instanz;
       }
    
       protected:
         Singleton() {}
    
       private:
         static Singleton *instanz;
    };
    
    Singleton* Singleton::instanz = 0;
    


  • ich benutzt es meistens so in der art, ist praktisch da man dann nur von Singleton ableiten muss und dann ne recht kleine uebersichtliche klasse hat - man muss nur sofern man das singleton verwendete - dispose aufrufen um den speicher frei zu geben,
    achso und man kann gut funktionsueberladungen erzwingen #gg
    Singleton.h

    template <class T>
    class Singleton
    {
    private:
    	static T* _instance;
    protected:
    	Singleton(){}
    public:
    	static T* instance()
    	{
    		if(!_instance)
    			_instance = new T();
    		return _instance;
    	}
    	static void dispose()
    	{
    		delete _instance;
    		_instance = 0;
    	}
    	virtual ~Singleton()
    	{
    		_instance = 0;
    	}
    };
    template <class T>
    T* Singleton<T>::_instance = 0;
    

    Using.h

    class Using : public Singleton<Using>
    {
    private:
    	friend class Singleton<Using>;
    
    protected:
    	virtual ~Using(void)
    	{
    		close();
    	}
    public:
    	static Using *instance()
    	{
    		return Singleton<Using>::instance();
    	}
    };
    

    .
    .
    Using::instance()->func();
    Using::instance()->dispose();



  • Wann wird die atexit funktion aufrufen?

    atexit( &Singleton::destroy );
    

    ??

    Was ist mit dem:

    static void Singelton::Destroy(){
      if( instanz) delete instanz;
    }
    
    {
    Singelton *p= exemplar();
    .
    .
    .
    .
    p->Destroy();
    
    }
    


  • Okay, welchen Sinn hat das mit dem Zeiger eigentlich? Wieso verwendest Du nicht folgenden Code:

    static singleton& instance() {
        static singleton the_instance;
        return the_instance;
    }
    


  • Viele wege füheren nach rom.. aber genau diesen hab ich gesucht^^
    hätte ich auch selber drauf kommen können 👎



  • Wenn man selbst Kontrolle über die Lebenszeit von Singletons haben will, kommt man fast nicht darum, die Persistenz mit atexit() selbst zu kontrollieren.



  • Tachyon schrieb:

    Wenn man selbst Kontrolle über die Lebenszeit von Singletons haben will, kommt man fast nicht darum, die Persistenz mit atexit() selbst zu kontrollieren.

    äh ... was spricht gegen meinen "Abräumer" ?

    Konrad Rudolph schrieb:

    Okay, welchen Sinn hat das mit dem Zeiger eigentlich? Wieso verwendest Du nicht folgenden Code:

    static singleton& instance() {
        static singleton the_instance;
        return the_instance;
    }
    

    Das geht bestimmt oftmals gut - aber "lazy creation" kann man damit halt nicht machen (nur, für den Fall, dass man es braucht).
    und wie sieht's aus, wenn man ein parametrisiertes instance() anbieten möchte ? (wobei das Schwierigkeiten beim 2. Aufruf bereitet)

    Gruß,

    Simon2.



  • , dass man dann nicht selbst die kontrolle hat?



  • Simon2 schrieb:

    Tachyon schrieb:

    Wenn man selbst Kontrolle über die Lebenszeit von Singletons haben will, kommt man fast nicht darum, die Persistenz mit atexit() selbst zu kontrollieren.

    äh ... was spricht gegen meinen "Abräumer" ?

    Gruß,

    Simon2.

    Das Dead-Refference-Problem. Es kann sein, dass der Destruktor von Deinem Aufräumer getriggert wird, dass Singleton aber noch benötigt wird.



  • hmm vlt. schrieb:

    , dass man dann nicht selbst die kontrolle hat?

    😕
    DAS ist ja gerade der Vorteil von RAII: Kontrolle an die Runtime abgeben, damit man es selbst nicht vergessen kann.

    Wer unbedingt "die Kontrolle behalten" will, sollte Assembler programmieren...
    😉

    Gruß,

    Simon2.



  • Tachyon hats schon gesagt. Da braucht man kein Assembler.



  • Tachyon schrieb:

    ...Das Dead-Refference-Problem...

    wohlklingender Name - hatte ich noch nicht gehört. 😉

    Natürlich kann man sich da in Abhängigkeiten verheddern (von denen mir allerdings momentan nur welche einfallen, die unter "schlechtes Design" fallen).
    Aber das geht Dir mit atexit() nicht anders: Auch hier muss jede Form von Abhängigkeit berücksichtigt werden ... ob ich das nun im "Abräumer" mache oder in atexit(), sollte IMHO keinen großen Unterschied machen.
    Da hat der Abräumer noch den Vorteil, dass ich auf den ja zur Laufzeit auch noch Zugriff habe, so dass Objekte ihre Abhängigkeiten da hinterlegen können.

    Gruß,

    Simon2.



  • hmm vlt. schrieb:

    Tachyon hats schon gesagt. Da braucht man kein Assembler.

    Habe ich behauptet, dass man zur Lösung dieses Problems Assembler braucht ?
    Übrigens: Wenn Du keine blöden Antworten haben möchtest, solltest Du evtl. dazu übergehen, Deine Standpunkte verständlich darzulegen.
    Wen jemand in "Ein-Satz-Statements" kommuniziert, ist nicht immer die Umwelt schuld, wenn sie einen mißversteht.

    Gruß,

    Simon2.



  • Also Andrei Alexandrescu schlägt in "Modern C++ Design: Generic Programming and Design Patterns Applied" vor, in Fällen, wo das Singlton u.U. von z.B. anderen statitischen Objekten zum Aufräumen oder für andere Zwecke benötigt wird vor, entweder die Persistenz mit Prioritäten zu sichern, oder das Singleton wiederauferstehend gesatalten. Also es so zu bauen, dass es zwar zu jeder beliebigen Zeit zerstört werden kann, es aber wieder aufersteht, wenn es nach seiner Zerstörung doch noch einmal benötigt wird. Als Beispiel nimmet ein ein Logging-Singleton wo fehler von anderen Singletons beim Abräumen geloggt werden.
    Insgesamt gibt es aber kein "Universal-Singleton", mit dem alle Probleme auf einmal gelöst werden können.



  • Simon2 schrieb:

    äh ... was spricht gegen meinen "Abräumer" ?

    Der ist natürlich als eigenes Micro-Design Pattern klasse.

    Konrad Rudolph schrieb:

    Okay, welchen Sinn hat das mit dem Zeiger eigentlich? Wieso verwendest Du nicht folgenden Code:

    static singleton& instance() {
        static singleton the_instance;
        return the_instance;
    }
    

    Das geht bestimmt oftmals gut - aber "lazy creation" kann man damit halt nicht machen (nur, für den Fall, dass man es braucht).

    Meine Variante *ist* lazy. Insbesondere wird nie eine Instanz von 'singleton' erstellt, es sei denn, man ruft 'instance' auf.

    und wie sieht's aus, wenn man ein parametrisiertes instance() anbieten möchte ? (wobei das Schwierigkeiten beim 2. Aufruf bereitet)

    Stimmt, das geht dann nicht mehr. In diesem Fall hat man aber eh keinen reinen Singleton mehr und benötigt irgendeine Art Factory.



  • Simon2 schrieb:

    Das geht bestimmt oftmals gut - aber "lazy creation" kann man damit halt nicht machen (nur, für den Fall, dass man es braucht).
    und wie sieht's aus, wenn man ein parametrisiertes instance() anbieten möchte ? (wobei das Schwierigkeiten beim 2. Aufruf bereitet)

    Wie "Lazy" soll denn das Erzeugen noch werden? 🙂



  • Simon2 schrieb:

    hmm vlt. schrieb:

    Tachyon hats schon gesagt. Da braucht man kein Assembler.

    Habe ich behauptet, dass man zur Lösung dieses Problems Assembler braucht ?
    Übrigens: Wenn Du keine blöden Antworten haben möchtest, solltest Du evtl. dazu übergehen, Deine Standpunkte verständlich darzulegen.
    Wen jemand in "Ein-Satz-Statements" kommuniziert, ist nicht immer die Umwelt schuld, wenn sie einen mißversteht.

    Warum hast du denn überhaupt Assembler erwähnt? Das hat schon da keinen Sinn gemacht, wo du es gepostet hast, weil es nix mit dem Thema zu tun hat, sondern einfach nur danach aussieht.



  • hmm vlt. schrieb:

    ...Warum hast du denn überhaupt Assembler erwähnt? ...

    Nun, erstmal war es "augenwinkernd" (habe ich ja sogar mit einem passenden Smilie).
    Und zum zweiten hattest Du als einziges Argument gegen meinen Vorschlag einen Mangel an Kontrolle gebracht. Mit der Erwähnung von Assembler (als Beispiel absurder Übertreibung) wollte ich das Augenmerk darauf lenken, dass "Kontrolle haben wollen" nicht das einzige Kriterium für oder gegen eine Programmiertechnik sein kann.
    (eben weil jemandem, für den das das einzige Kriterium wäre, höchstens Assembler übrig bliebe ...)
    Da allerdings von Dir kein anderes erwähnt wurde, hoffte ich da auch mehr (ein Wunsch, der allerdings bis jetzt unerfüllt ist).

    Ich hoffe, das ist jetzt klarer geworden und wir können uns wieder der eigentlichen Frage zuwenden.

    Gruß,

    Simon2.



  • Konrad Rudolph schrieb:

    ...
    Meine Variante *ist* lazy. Insbesondere wird nie eine Instanz von 'singleton' erstellt, es sei denn, man ruft 'instance' auf....

    Stimmt natürlich ! Mein Fehler !
    Ist Deine Variante eigentlich bzgl. der von Tachyon angesprochenen Abhängigkeiten zuverlässiger ?
    Eigentlich auch nicht, oder ?

    Konrad Rudolph schrieb:

    ...

    und wie sieht's aus, wenn man ein parametrisiertes instance() anbieten möchte ? (wobei das Schwierigkeiten beim 2. Aufruf bereitet)

    Stimmt, das geht dann nicht mehr. In diesem Fall hat man aber eh keinen reinen Singleton mehr und benötigt irgendeine Art Factory.

    Ja - ich war ja von dem Argument sowieso nicht sooo überzeugt.

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Konrad Rudolph schrieb:

    ...
    Meine Variante *ist* lazy. Insbesondere wird nie eine Instanz von 'singleton' erstellt, es sei denn, man ruft 'instance' auf....

    Stimmt natürlich ! Mein Fehler !
    Ist Deine Variante eigentlich bzgl. der von Tachyon angesprochenen Abhängigkeiten zuverlässiger ?
    Eigentlich auch nicht, oder ?

    Da die Aufräum-Reihenfolge statischer lokaler Objekte nicht definiert ist, wohl nicht (→3.6.3.2).


Anmelden zum Antworten