Nur ein Objekt



  • Eine Frage: Wo rufst du den Destruktor auf?

    Meyer'sche Singleton:

    template <class class_type>
    class singleton
    {
        singleton(singleton const&);
        singleton& operator=(singleton const&);
        singleton();
        ~singleton();
    
    public:
        inline static class_type& instance() { static class_type instance; return instance; }
    }
    


  • ob es bei ansi c++ jetzt wenn man es genau so schreibt erst bei der ersten benutzung initialisiert wird oder nicht ist doch egal
    vllt wird es in java, c++/cli, c#, etc. ja bereits sofort angelegt, das design pattern ist dasselbe

    ich finde nichts schlechtes daran es direkt anzulegen anstatt in der GetInstance() methode ein

    if(instance == NULL)
        instance = new Singleton();
    

    wenn dein singleton ein bitmap manager ist zb in einem zeichenprogramm und du ihn allein schon bei der initialisierung der GUI verwendest und sowieso 100% wenn man das programm benutzt, klar wieso nicht

    der einzige fall wo ich die if abfrage machen würde und erst das singleton initialisieren würde wenn ich es zum ersten mal brauche wäre wenn es sich um was "großes" handelt

    beispielsweise ein singleton networkking betreibt und erst zu einem server connected und eine connection aufbaut mit der er die daten hin und her schickt weil sie nicht lokal gemanaged werden

    dann macht es natürlich sinn ihn erst anzulegen wenn man ihn benötigt

    also bei objekten wo das anlegen viel aufwand dastellt, vllt eine statische Initialize() methode die einmal das objekt erstellt

    es kommt immer auf den scope an in dem man sowas programmiert



  • naja, wenn man das Ganze in eine Art Smartpointer wrappt geht es ohne Probleme, dann wird ja der Destruktor implizit spätestens beim Schließen des Programmes aufgerufen (jedenfalls der des Smartpointers) und dieser wiederum zerstört die Singleton-Instanz. z.B.:

    class SP;
    
    class Singleton
    {
        friend class SP;
        private:
           static SP singleton;
        public:
           static Singleton & getInstance ();
    };
    
    class SP
    {
        Singleton * instance;
    public:
        SP(): instance( new Singleton() ) {}
        Singleton * operator * () { return instance; }
        ~SP()
        {
            delete instance;
        }
    };
    
    SP Singleton::singleton;
    Singleton & Singleton::getInstance() { return *(*singleton); }
    

    So gehts auch wunderbar und der Destruktor wird sogar aufgerufen



  • Äh, ich habe noch mal eine Frage zu den SingleTon.

    Auf folgender Seite:
    http://de.wikipedia.org/wiki/Singleton_(Entwurfsmuster)

    Bei den Beispielen in C++. Wie kann ich jetzt das eine Objekt erzeugen???



  • In dem du

    Singleton::getInstance()
    

    verwendest. Da es eine statische methode ist kannst du sie ohne Objekt verwenden.
    Schau auch mal hier
    http://www.oop-trainer.de/Themen/Singleton.html



  • Naja das der Destruktor nicht aufgerufen wird ist sowieso total schnuppe. Alle Resourcen werden bei Programmende, sofern das Betriebssystem nicht total auf den Kopp gefallen ist, zurückgegeben.
    Wenn man sowas als "schlechten Stil" bezeichnet, kann man immer noch eine DestroySingleton() Funktion machen oder anstatt new

    static singleton singleton::instance = singleton();
    

    machen. Das läuft allerdings fast auf das selbe wie oben hinaus.



  • c++-er schrieb:

    Naja das der Destruktor nicht aufgerufen wird ist sowieso total schnuppe. Alle Resourcen werden bei Programmende, sofern das Betriebssystem nicht total auf den Kopp gefallen ist, zurückgegeben.

    Dies stimmt so nicht ganz, kommt immer darauf an was es für Ressourcen sind. Zumal ein new an der Stelle sowas von unnötig ist und es mit einem Objekt ohne all diese Probleme geht.

    c++-er schrieb:

    Wenn man sowas als "schlechten Stil" bezeichnet, kann man immer noch eine DestroySingleton() Funktion machen oder anstatt new

    static singleton singleton::instance = singleton();
    

    machen. Das läuft allerdings fast auf das selbe wie oben hinaus.

    Eben nicht. Und ja es ist "schlechten Stil" und auch eine DestroySingleton()-Funktion geht an dem Sinn und Zweck eines Singletons vorbei.

    Mag es dir vielleicht kleinkariert erscheinen, wenn du wie ich an einer "historisch gewachsenen Anwendung" arbeitest, bist du froh möglichst viele Fallstricke zu vermeiden. Es reicht schon das noch genügend "historische Altlasten" in der Software sind, und durch Zeitdruck und mangelde Planung das ganze noch verschärft wird.

    cu André



  • asc schrieb:

    ... geht an dem Sinn und Zweck eines Singletons vorbei.

    Dann erklär mir mal den Sinn und Zweck eines Singleton. Wenn ich nur eine Instanz haben will dann lege ich nur eine Instanz an. Deshalb ein Singleton zu benutzen ist total schwachsinnig(meine Meinung!). Außerdem bindet man sich (bei großen Projekten) mittel-/langfristig mit Singletons einen riesigen Klotz ans Bein. Man läuft einfach Gefahr das man soviel Querverstrebungen hat, dass man nicht mehr weiß wo hinten und vorne ist und dies macht die Wartung einfach ungeheuer schwierig.



  • c++-er schrieb:

    asc schrieb:

    ... geht an dem Sinn und Zweck eines Singletons vorbei.

    Dann erklär mir mal den Sinn und Zweck eines Singleton.

    Mein "geht am Sinn und Zweck" vorbei bezieht sich auf dein DestroySingleton(). Wenn man schon ein Singelton einsetzt, so weiß man meist nicht wann man den letzten Zugriff hat. Daher ist es unsinnig sich um die Freigabe kümmern zu müssen (Sprich Fehlerhafte Implementierung des Singletons).

    c++-er schrieb:

    Wenn ich nur eine Instanz haben will dann lege ich nur eine Instanz an. Deshalb ein Singleton zu benutzen ist total schwachsinnig(meine Meinung!).

    Gut, dann sag mir mal wie du auf diese eine Instanz zugreifen willst. Wenn du sie überall durchreichst, okay. Aber nehmen wir mal an du hast z.B. Allgemeine Einstellungen zu deiner Anwendung die nur einmal eingelesen werden müssen. Ich sehe hier eben den Sinn des Singletons das diese - bei der ersten Anfrage der Einstellung - eingelesen werden, und anschließend bereit stehen. Da die Einstellungen an mehreren Stellen verwendet werden, kann man nicht genau sagen wann sie nicht mehr verwendet werden. Ein Singleton räumt sich selber auf.

    c++-er schrieb:

    Außerdem bindet man sich (bei großen Projekten) mittel-/langfristig mit Singletons einen riesigen Klotz ans Bein. Man läuft einfach Gefahr das man soviel Querverstrebungen hat, dass man nicht mehr weiß wo hinten und vorne ist und dies macht die Wartung einfach ungeheuer schwierig.

    Nenn mir eine sinnvolle Alternative für mein Beispiel mit den Programmeinstellungen. Eine globale Variable ist es nicht (Die hat zudem den Nachteil der ungewissen Anlagereihenfolge), die Übergabe an jedes Objekt ist es mit Sicherheit auch nicht.

    Ja, man sollte nicht mit Singletons übertreiben. Aber einen Sinn und Zweck haben sie schon.

    cu André



  • Komplett statische Klassen wären eine Möglichkeit, sind aber nicht so flexibel zu erweitern, sollte man mal mehrere Instanzen benötigen. Auch sind sie nerviger zu schreiben.


Anmelden zum Antworten