Singletons



  • Xebov schrieb:

    Ich evrstehe nicht ganz worauf du hinaus willst? Ich bezog mich darauf das ich mit der Singleton keine globale Variable mehr brauche da der Zugriff von überall ja möglich ist. Das man Singletons nicht für jede Kleinigkeit einsetzt setze ich jetzt einfach mal v******.

    Angenommen du benötigst eine globale Zugriffsstelle für irgendwas, wobei du aber die Implementierung von irgendwas austauschbar machen willst. Dann würde sich z.B. eine globale Referenz (also im Endeffekt auch eine Art globale Variable) anbieten. Wie würdest du das mit einem Singleton realisieren?



  • Die globale Referenz hat aber nur den Vorteil, daß Du
    cout.foo();
    schreiben kannt.

    Wenn ich bereit bin,
    cout().foo();
    zu schreiben, brauche ich keine globalen Referenzen mehr.



  • Oder wenn man es mit dem Gewissen vereinbaren kann: Makros. Bei Singletons finde ich die legitim, denn jedes Mal MySingleton.GetInstance().DoSomething(); zu schreiben ist mühsam und bringt nicht wirklich was. Wenns nur ab und zu vorkommt, kann mans schon so machen.

    Bei globalen Referenzen muss man je nach Ziel auch aufpassen, dass es bereits existiert, wenn die Referenz erstellt wird. Oder dass die Referenz bereits initialisiert ist, wenn man auf sie zugreift.



  • Es geht mir nicht um eine Kurzschreibweise. Folgendes Beispiel:

    class Base
    {
    public:
    	virtual void foo() = 0;
    };
    
    class Derived1 : public Base
    {
    public:
    	virtual void foo()
    	{
    	}
    };
    
    class Derived2 : public Base
    {
    public:
    	virtual void foo()
    	{
    	}
    };
    
    extern Base& g_something;
    
    // irgendwo modulglobal, oder sonstwas
    Derived2 bla;
    Base& g_something = bla;
    
    // oder
    Derived1 bla;
    Base& g_something = bla;
    

    Nexus schrieb:

    Bei globalen Referenzen muss man je nach Ziel auch aufpassen, dass es bereits existiert, wenn die Referenz erstellt wird. Oder dass die Referenz bereits initialisiert ist, wenn man auf sie zugreift.

    Die Referenz muss doch initialisiert sein, ansonsten streikt der Compiler bereits.



  • David_pb schrieb:

    Die Referenz muss doch initialisiert sein, ansonsten streikt der Compiler bereits.

    Nicht, wenn eine Deklaration der Referenz vorliegt.

    // Header
    extern MyClass& Reference;
    
    // Implementierungsdatei
    MyClass& Reference = ...;
    

    Da die Initialisierungsreihenfolge globaler Variablen in unterschiedlichen Übersetzungseinheiten nicht festgelegt ist, kann es sein, dass ein Zugriff auf Reference erfolgt, bevor die Referenz initialisiert wurde.

    Aber solche Fälle scheinen mir generell eher realitätsfern. Oder setzt du häufig globale Referenzen ein?



  • Nexus schrieb:

    Aber solche Fälle scheinen mir generell eher realitätsfern. Oder setzt du häufig globale Referenzen ein?

    Mag sein, das solche Fälle selten sind. Aber den Fall gibt es trotzdem und Singletons sind eben kein kompletter Ersatz für globale Variablen, selbst wenn es einige Parallelen gibt.



  • David_pb schrieb:

    Mag sein, das solche Fälle selten sind. Aber den Fall gibt es trotzdem und Singletons sind eben kein kompletter Ersatz für globale Variablen, selbst wenn es einige Parallelen gibt.

    Hä? Versteh ich nicht.
    Warum brauchst Du globale Referenzen? Warum kann der Benutzer nicht g_something() statt g_something schreiben? Willst Du für verschiedene Übersetzungseinheiten andere Bedeutungen hinter der Referenz haben? Das geht eigentlich auch mit g_something() statt g_something. Oder warum sonst?



  • Nein, ich will aber z.B. Vererbungspolymorphie verwenden können und die Implementierung die referenziert wird beim Initialisieren beliebig wählen. Falls der Fall mal real auftreten sollte wüsste ich spontan nicht wie das per Singleton realisierbar wäre, möglich das es ja irgendwie funktioniert?!



  • David_pb schrieb:

    Nein, ich will aber z.B. Vererbungspolymorphie verwenden können und die Implementierung die referenziert wird beim Initialisieren beliebig wählen. Falls der Fall mal real auftreten sollte wüsste ich spontan nicht wie das per Singleton realisierbar wäre, möglich das es ja irgendwie funktioniert?!

    Vererbungspolymorphie kann die Funktion auch.
    Und beliebige Wahl hast Du mit

    namespace {
       Base& g_something(){
          return Derived1::getInstance();
       }
    }
    


  • unskilled schrieb:

    find ich zwar eigtl auch toll, aber dummerweise kann man die zerstörungs-reihenfolge eben nicht festlegen : <

    bb

    Das problem hab ich bei mir mit ner ShutDown Methode gelöst. Ich rufe am beginn von Main einmal getInstance und dann init auf um alles Ordnungsgemäß zu Initalisieren und am ende von Main ShutDown, damit ist die Instanz zwar nicht weg, aber die Arbeit ist erledigt, also Speicher freigegeben usw. Man muß dann nur aufpassen das danach nicht irgendwelche anderen elemente was wollen, da ist dann beim Herunterfahren etwas vorrausplanung gefragt.


Anmelden zum Antworten