[C++] Speicherfreigabe bei statischem Singleton

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von BeRsErKeR »

Ihr müsst euch nicht wiederholen. Mir sind die genannten Punkte (Nachteile von Singletons, Nachteile von globalen Variablen) durchaus bekannt und ich habe auch diesen Thread hier komplett gelesen. Ich wollte nun eigentlich auch keine Begründungen, warum irgendwas so ist wie es ist. Mich stört eher die Art wie hier teilweise diskutiert wird. Ich habe nichts dagegen wenn man über bestimmte Ansätze, Patterns, etc diskutiert, das finde ich sogar richtig und wichtig, aber in meinen Augen reicht es, wenn man sachlich diskutiert was Vorteile und Nachteile sind. Man muss nicht immer einen "das ist böse"-Aufkleber drauf kleben.

CodingCat hat geschrieben:
BeRsErKeR hat geschrieben:Ich persönlich nutze sehr viele Singletons in meinem Projekt, [...] sie erfüllen die Anforderungen, die ich habe und da ist mir scheißegal wozu sie mal entworfen wurden.
Klar kannst du auch mit Singletons erfolgreich programmieren, du programmierst dann eben schlichtweg nicht objektorientiert. ;-)
Das ist doch aber nichts Schlimmes. C++ bietet nun mal die Möglichkeit nicht alles objektorientiert zu lösen und in vielen Fällen ist das auch nicht ratsam. Globale Variablen können ja bekanntlich sogar die Kapselung in gewissen Situationen erhöhen und für viele Sachen ist es schlichtweg unnötig objektorientiert zu arbeiten. Der Logger ist ja das beste Beispiel.

CodingCat hat geschrieben:
BeRsErKeR hat geschrieben:Wenn ich mich von meinem letzten Floh, der mir in den Kopf gesetzt wurde, nämlich "alles globale in OO ist böse", erholt habe
Das hat prinzipiell gar nichts mit Objektorientierung zu tun, globale Variablen/Operationen/Objekte/Zustände haben mitunter folgende Nachteile: Unabsehbare Seiteneffekte, undurchsichtige Abhängigkeiten, geringere Flexibilität, geringe Wiederverwendbarkeit.
Insbesondere die ersten beiden Punkte sind eine sehr ernste Sache: Wenn nicht klar ist, welche Variablen/Objekte/Zustände durch eine Operation verändert werden, wird es schwierig bis unmöglich, Annahmen über aktuelle Werte und Zustände zu machen, Invarianten zu erhalten sowie anderweitige effektive Konsistenzerhaltung zu betreiben.
Wenn nicht klar ist, welche Module/Operationen von welchen anderen Modulen/Operationen abhängen, ist es sehr leicht, in zyklische Abhängigkeiten zu verfallen, dies reicht von undefiniertem Verhalten mangels korrekter isolierter Initialisierbarkeit bis hin zu undurchschaubaren Endlosrekursionen bei der globalen Verteilung von Ereignissen.
Das ist mir schon bewusst. Aber gerade weil auf vielen Seiten, in Foren und sogar in Büchern globale Variablen und Funktionen dermaßen niedergemacht wurden, wurde man schon vorsichtig. Ich glaube nicht, dass ich der einzige Mensch bin, der lange Zeit einen Bogen um globalen Kram in C++ gemacht hat. Ich hätte mir da eine sachliche Beleuchtung gewünscht, die z.B. auch herausstellt welche Vorteile globale Variablen haben können und das sie doch ihre Daseinsberechtigung haben. Und genauso wünsche ich mir halt auch eine objektive Betrachtung von Singletons (was außer Frage natürlich auch stellenweise vorhanden war). Das Pattern an sich finde ich nicht sinnlos oder falsch. Und wenn es jemand "schöner" findet eine globale Instanz in einer Klasse zu verpacken finde ich da nichts schlimm dran. Klar sollte derjenige dann schon wissen, dass es letztlich nur eine globale Instanz ist, aber ich weiß nicht ob alles, was nicht dem idealen Weg entspricht, gleich immer falsch sein muss. Es ist ein anderer Ansatz der vielleicht auch mehr Zeit beansprucht, aber als ob es nicht etliche solcher Dinge in der Programmierung gibt. Ich kam bislang super mit meinen Singletons zurecht und fand es sehr bequem sie zu nutzen. Für die Implementierung habe ich mich auch nicht tot gemacht. Ich will hier auch nicht für Singletons werben oder sagen, dass sie ganz toll sind. Aber genauso wenig möchte ich halt, dass es in die andere Richtung geht. Ihr müsst euch eigentlich auch gar nicht in irgendeiner Weise rechtfertigen, ich wollte einfach nur mal einwerfen, dass ich es begrüßen würde, wenn man etwas objektiver an die Sache geht. Und ganz wichtig, ich habe nicht jeden angesprochen der hier gepostet hat. Beim Rauslesen ist mir halt besonders dot aufgefallen. Da schwang mitunter ein recht negativer Ton mit, aber das ist halt auch der Nachteil an Medien wie Foren und Chats. Es fehlen Mimik, Gestik, Intonation usw. Da interpretiert man teilweise mehr rein, als eigentlich da ist.

Von daher. Nichts für ungut. Es war mir ein Bedürfnis das mal los zu werden. ;)
Ohne Input kein Output.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von CodingCat »

Das Pattern an sich finde ich nicht sinnlos oder falsch. Und wenn es jemand "schöner" findet eine globale Instanz in einer Klasse zu verpacken finde ich da nichts schlimm dran. Klar sollte derjenige dann schon wissen, dass es letztlich nur eine globale Instanz ist, aber ich weiß nicht ob alles, was nicht dem idealen Weg entspricht, gleich immer falsch sein muss. Es ist ein anderer Ansatz der vielleicht auch mehr Zeit beansprucht, aber als ob es nicht etliche solcher Dinge in der Programmierung gibt.
Das stimmt mich jetzt wirklich traurig. Ich habe dir mit Abstand die sachlichste, umfassendste und präziseste Antwort geschrieben, die ich seit langem irgendwem geschrieben habe.
Ich habe versucht, zu beleuchten, dass SELBST für das Logging, bei dem ein globaler Ansatz, wie in ebendieser Antwort illustriert, durchaus vertretbar sein kann, ein Singleton in aller Regel keine Daseinsberechtigung hat.

Ich habe ausführlichst versucht, zu zeigen, dass es eben nicht um "schöner finden" geht, sondern dass es handfeste Gründe gibt, die Dinge wenn irgendmöglich ohne Singletons zu lösen. Es ist kein anderer Ansatz, der "vielleicht mehr Zeit beansprucht". Sind wir ehrlich, du hast es selbst zuvor in einem Post gesagt, der zusätzliche Aufwand, aus einer Klasse ein Singleton zu machen, ist ein Witz. Aber Sinn und Zweck eines Singletons ist es, die Konstruktion zu beschränken, NICHT der globale Zugriff. Und sofern es nicht einen driftigen Grund gibt, die Anzahl der instanziierten Objekte zu begrenzen, IST das Singleton OBJEKTIV sinnlos und die falsche Wahl.
Das ist mir schon bewusst. Aber gerade weil auf vielen Seiten, in Foren und sogar in Büchern globale Variablen und Funktionen dermaßen niedergemacht wurden, wurde man schon vorsichtig. Ich glaube nicht, dass ich der einzige Mensch bin, der lange Zeit einen Bogen um globalen Kram in C++ gemacht hat. Ich hätte mir da eine sachliche Beleuchtung gewünscht, die z.B. auch herausstellt welche Vorteile globale Variablen haben können und das sie doch ihre Daseinsberechtigung haben.
Abgesehen von so elementaren, isolierten und naturgemäß zentralen Aufgaben wie Logging IST es nach wie vor ratsam, globale Variablen/Objekte/Zustände zu meiden, auch dafür habe ich dir mehrere sachliche Gründe geliefert.
Ich kam bislang super mit meinen Singletons zurecht und fand es sehr bequem sie zu nutzen.
Du sagst es, sie sind bequem. Das wars dann aber auch. Wie dot sagt, ist auch mir kein einziger Fall bekannt, in dem ein Singleton irgendeine Daseinsberechtigung hätte. Wenn du um der Bequemlichkeit Willen zu Lasten guten Designs Entscheidungen triffst, ist das, solange du der einzige Entwickler und Nutzer dieser Software bist, ganz allein deine Sache. Aber dann suche bitte nicht zwanghaft nach objektiven Begründungen, sondern erkenne, dass es dir alleine um die Bequemlichkeit geht. Und sei dir bewusst, dass diese Entscheidung dich in großen Projekten im Nachhinein sehr viel mehr kosten kann, kosten wird, als du mit deiner Bequemlichkeit je gespart hast.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von dot »

Auch wenn ich bei dem Thema gern etwas sarkastisch werd, so denk ich doch, dass genügend objektive Gründe genannt wurden. Offenbar gefallen sie dir nicht, aber das können wir leider nicht ändern. Ich hätte kein Problem damit, auch objektive Vorteile des "Singleton" Pattern zu diskutieren. Ich kenn nur leider keine (kein Sarkasmus, das mein ich wirklich ernst). Niemand wird dich dran hindern, weiter mir "Singletons" zu arbeiten. Was Bequemlichkeit betrifft, bin ich mal so frei, zu vermuten, dass du es einfach nur nicht besser kennst. Ich finde Singletons jedenfalls alles andere als bequem. Warum ständig irgendwo ein ->GetInstance() tippen und den Code damit zumüllen, wenns auch ohne geht!? Ich kann dir nur empfehlen, es mal ohne zu versuchen ;)

Hier nochmal ein paar hoffentlich doch objektive Probleme des Singleton Pattern zusammengefasst:
  • Verschleierung von Abhängigkeiten (big issue!)
  • Multithreading
  • globaler Zustand, macht automatisches Testing zur Qual
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von BeRsErKeR »

CodingCat hat geschrieben:
Das Pattern an sich finde ich nicht sinnlos oder falsch. Und wenn es jemand "schöner" findet eine globale Instanz in einer Klasse zu verpacken finde ich da nichts schlimm dran. Klar sollte derjenige dann schon wissen, dass es letztlich nur eine globale Instanz ist, aber ich weiß nicht ob alles, was nicht dem idealen Weg entspricht, gleich immer falsch sein muss. Es ist ein anderer Ansatz der vielleicht auch mehr Zeit beansprucht, aber als ob es nicht etliche solcher Dinge in der Programmierung gibt.
Das stimmt mich jetzt wirklich traurig. Ich habe dir mit Abstand die sachlichste, umfassendste und präziseste Antwort geschrieben, die ich seit langem irgendwem geschrieben habe.
Ich habe versucht, zu beleuchten, dass SELBST für das Logging, bei dem ein globaler Ansatz, wie in ebendieser Antwort illustriert, durchaus vertretbar sein kann, ein Singleton in aller Regel keine Daseinsberechtigung hat.
Das habe ich nicht bezweifelt und du musst dich nicht bei jedem meiner Statements angesprochen fühlen. Hier wurde natürlich auch sachlich diskutiert, auch von deiner Seite.
CodingCat hat geschrieben:Ich habe ausführlichst versucht, zu zeigen, dass es eben nicht um "schöner finden" geht, sondern dass es handfeste Gründe gibt, die Dinge wenn irgendmöglich ohne Singletons zu lösen. Es ist kein anderer Ansatz, der "vielleicht mehr Zeit beansprucht". Sind wir ehrlich, du hast es selbst zuvor in einem Post gesagt, der zusätzliche Aufwand, aus einer Klasse ein Singleton zu machen, ist ein Witz. Aber Sinn und Zweck eines Singletons ist es, die Konstruktion zu beschränken, NICHT der globale Zugriff. Und sofern es nicht einen driftigen Grund gibt, die Anzahl der instanziierten Objekte zu begrenzen, IST das Singleton OBJEKTIV sinnlos und die falsche Wahl.
Man muss halt differenzieren ob man vom Singleton Pattern spricht oder von einer Singleton-Implementierung in C++ mit statischer Variable. Eine globale Instanz ist ja auch nur einmalig vorhanden, genauso wie die statische Variable eines Singletons. Soll heißen, das Singleton Pattern wurde natürlich dafür entworfen, die Konstruktion zu begrenzen, aber es hat in der Implementierung, die hier auch oft angesprochen wurde ganz einfach die Eigenschaft einer globalen Instanz, die in einer Klasse verpackt wurde. Und auch genau dieser Punkt wurde ja auch im Thread als Kritikpunkt gesehen, nämlich das ein Singleton (in der genannten Implementierungsform) eben nichts weiter ist als eine globale Instanz in einer Klasse. Und da gehe ich einfach nicht mit, dass das von Haus aus etwas schlimmes ist. Es ist wie Krishty anmerkte einfach eine Formsache und wer die Form mit Klasse mag, der soll sie doch benutzen. Von mir aus nennen wir es nicht Singleton, sondern "Globale Instanz in einer Klasse verpackt". Und das nutze ich recht gern. Dazu gab es halt Kritik, die eigentlich nichts mit dem Singleton Pattern zu tun hat, sondern eher mit globalen Instanzen.
CodingCat hat geschrieben:
Das ist mir schon bewusst. Aber gerade weil auf vielen Seiten, in Foren und sogar in Büchern globale Variablen und Funktionen dermaßen niedergemacht wurden, wurde man schon vorsichtig. Ich glaube nicht, dass ich der einzige Mensch bin, der lange Zeit einen Bogen um globalen Kram in C++ gemacht hat. Ich hätte mir da eine sachliche Beleuchtung gewünscht, die z.B. auch herausstellt welche Vorteile globale Variablen haben können und das sie doch ihre Daseinsberechtigung haben.
Abgesehen von so elementaren, isolierten und naturgemäß zentralen Aufgaben wie Logging IST es nach wie vor ratsam, globale Variablen/Objekte/Zustände zu meiden, auch dafür habe ich dir mehrere sachliche Gründe geliefert.
Ich finde leider den Link gerade nicht, aber da gab es mal einen schönen Artikel in dem gezeigt wird, dass globale Variablen (oder halt in einen namespace gepackt) oft sehr viel besser sind, als das ganze als Member von Klassen anzulegen. In diesem Artikel wurde z.B. für eine Klasse ein zugehöriger namespace ála MyClassVars angelegt, in dem "globale" oder besser "namespace-lokale" Variablen extra außerhalb der Klasse angelegt wurden und das ganze hatte den positiven Effekt, dass die Kapselung höher war, als mit Membervariablen. Ich schau mal ob ich den finde. Soll heißen ich habe schon einiges gesehen, wo Variablen außerhalb von Klassen weitaus effektiver und geeigneter waren. Von daher kann ich das nicht unterschreiben.
CodingCat hat geschrieben:
Ich kam bislang super mit meinen Singletons zurecht und fand es sehr bequem sie zu nutzen.
Du sagst es, sie sind bequem. Das wars dann aber auch. Wie dot sagt, ist auch mir kein einziger Fall bekannt, in dem ein Singleton irgendeine Daseinsberechtigung hätte. Wenn du um der Bequemlichkeit Willen zu Lasten guten Designs Entscheidungen triffst, ist das, solange du der einzige Entwickler und Nutzer dieser Software bist, ganz allein deine Sache. Aber dann suche bitte nicht zwanghaft nach objektiven Begründungen, sondern erkenne, dass es dir alleine um die Bequemlichkeit geht. Und sei dir bewusst, dass diese Entscheidung dich in großen Projekten im Nachhinein sehr viel mehr kosten kann, kosten wird, als du mit deiner Bequemlichkeit je gespart hast.
Ich weiß nicht so recht ob man hier von schlechtem Design sprechen kann. Ich sehe den Vorteil einer globalen Instanz innerhalb einer Klasse auch darin, dass man die Zugehörigkeit besser erkennt. Ich denke für Teammitglieder ist es auch einfacher, wenn sie nach einer GetInstance-Methode "suchen" müssen, als nach der richtigen globalen Instanz. In dem Fall finde ich eigentlich nur einen namespace, der direkt zur Klasse passt (wie oben erwähnt in der Art von namespace MyClassVars) mit der globalen Instanz besser. Wenn die globale Instanz aber irgendwo in einem übergeordneten namespace rumschwirrt oder schlimmer noch im globalen namespace, dann denke ich eher, dass das für andere schwieriger ist als mit einer globalen Instanz in der Klasse. Auch hier spreche ich eher von der C++ Implementierungsvariante und nicht vom Singleton-Pattern selbst.

dot hat geschrieben:Was Bequemlichkeit betrifft, bin ich mal so frei, zu vermuten, dass du es einfach nur nicht besser kennst.
Sagen wir mal "besser kanntest". Als ich anfing Singletons zu nutzen war mir vieles wirklich nicht bewusst. Dann kam die große Welle, in der Singletons verpönt waren. Das Hauptprobleme für die meisten Kritikpunkte sehe ich aber einfach in der Art wie man es in C++ implementieren muss. Das Pattern an sich findest du ja auch nicht von Grund auf falsch. Es wurde ja auch nicht umsonst entworfen. Wenn man für ein Singleton bessere Mittel hätte wie z.B. ein C++ Schlüsselwort wäre es sicher angenehmer und auch in manchen Situationen sinnvoll. Was die meisten doch eher stört, ist dass es sich einfach um eine globale Instanz in einer Klasse handelt. Das hat aber an sich nichts mit dem Pattern zu tun, sondern eher mit C++. Es gab zwar auch einige Statements, die Singletons (das Pattern) per se nicht als gut erachten, aber die Mehrheit der Kritik bezieht sich meiner Meinung nach auf die Implementierung in C++. Ich nutze die Singleton-C++-Implementierung einfach wenn ich eine globale Instanz hübsch in einer Klasse verpacken will, vorallem aus o.g. Grund der Zugehörigkeitserkennung. Ich weiß halt, dass wenn ich die Instanz der Klasse haben will, einfach bei ihr über GetInstance anfragen kann. Es geht auch anders, klar, aber ich mag diese Form mehr als eine globale Instanz im Nirvana der namespaces. Das ist aber nur meine persönliche Einstellung.
dot hat geschrieben:Ich finde Singletons jedenfalls alles andere als bequem. Warum ständig irgendwo ein ->GetInstance() tippen und den Code damit zumüllen, wenns auch ohne geht!? Ich kann dir nur empfehlen, es mal ohne zu versuchen ;)
Und wieder reden wir eigentlich nicht über das Singleton-Pattern, sondern die C++ Implementierung. Aber mal davon ab. Ich schreibe eigentlich ganz gern ein wenig mehr Code, wenn ich dadurch die Lesbarkeit erhöhe. Bei einer globalen Variable namens MyGlobalInstance wüsste ich nicht unbedingt, ob es da vielleicht nicht noch andere Instanzen der Klasse gibt und wenn ich sie ungünstig benenne weiß ich vielleicht nicht einmal, was diese Instanz ist oder wofür. Bei einem MyClass::GetInstance() weiß ich, dass ich mir eine Instanz eben dieser Klasse hole und außerhalb kann mir dabei sogar gänzlich egal sein, wie mir intern diese Instanz geliefert wird. Aber auch das ist wieder Geschmackssache. Es soll sogar Leute geben, die Operatoren verabscheuen und anstelle von a = b +c; lieber a.assign(b.add(c)); nutzen. Von daher sollte man persönliche Vorlieben nicht immer auch auf andere projezieren. Aber ich will eigentlich gar keine Diskussion ála "das ist besser als das" vom Stapel brechen; das muss schon jeder für sich entscheiden. Ich mag globale Instanzen in Klassen und auch GetInstance. Jedenfalls mehr als globale Variablen ohne eben genanntes.
dot hat geschrieben:Hier nochmal ein paar hoffentlich doch objektive Probleme des Singleton Pattern zusammengefasst:
  • Verschleierung von Abhängigkeiten (big issue!)
  • Multithreading
  • globaler Zustand, macht automatisches Testing zur Qual
Betrifft meiner Meinung nach auch eher die C++ Implementierung und nicht das Pattern an sich.
Ohne Input kein Output.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von CodingCat »

Es ist eigentlich alles gesagt. Es wäre nett, wenn du mal versuchen würdest, unsere Antworten zu verstehen, statt dich endlos in schwammigen Konterposts zu wiederholen. Dann würde dir auffallen, dass wir uns so oft wiederholen müssen, um deine vermischten Antworten immer wieder mühsam Punkt für Punkt zu korrigieren. WIR reden hier sehr wohl vom Singleton-MUSTER, und zwar solange, bis wir das Gefühl haben, dass du verstanden hast, worum es eigentlich geht.
Man muss halt differenzieren ob man vom Singleton Pattern spricht oder von einer Singleton-Implementierung in C++ mit statischer Variable.
Nein, muss man nicht. Singleton heißt: NUR EINE INSTANZ. Globale Instanz heißt: GLOBALE ODER STATISCHE VARIABLE. Wenn du Singleton schreibst, heißt das, wir reden von Konstruktionsbeschränkung.
Soll heißen, das Singleton Pattern wurde natürlich dafür entworfen, die Konstruktion zu begrenzen, aber es hat in der Implementierung, die hier auch oft angesprochen wurde ganz einfach die Eigenschaft einer globalen Instanz, die in einer Klasse verpackt wurde. Und auch genau dieser Punkt wurde ja auch im Thread als Kritikpunkt gesehen, nämlich das ein Singleton (in der genannten Implementierungsform) eben nichts weiter ist als eine globale Instanz in einer Klasse. Und da gehe ich einfach nicht mit, dass das von Haus aus etwas schlimmes ist.
Es IST von Haus aus bis auf ganz ganz wenige Ausnahmen etwas schlimmes, Abhängigkeiten, blabla ...
Betrifft meiner Meinung nach auch eher die C++ Implementierung und nicht das Pattern an sich.
Nein, das hat mit C++ absolut nichts zu tun, die Folgen von globalen Objekten/Variablen/Zuständen sind in allen Sprachen dieselben.
Bei einer globalen Variable namens MyGlobalInstance wüsste ich nicht unbedingt, ob es da vielleicht nicht noch andere Instanzen der Klasse gibt und wenn ich sie ungünstig benenne weiß ich vielleicht nicht einmal, was diese Instanz ist oder wofür. Bei einem MyClass::GetInstance() weiß ich, dass ich mir eine Instanz eben dieser Klasse hole [...]
Genau DAS ist die Idee bei der Trennung von Klassen und Objekten: Dass du nicht weißt, wieviele Objekte es gibt, dass du es nicht wissen MUSST, wieviele Objekte es gibt, sondern dass du genau dasjenige Objekt nutzt, welches du gerade benötigst, und die anderen unabhängig davon koexistieren können, ohne in irgendeiner Weise beeinflusst zu werden. Und genau DAS ist das Problem von Signletons und NICHT von globalen Instanzen oder Implementierungen, dass sie in Klassen getarnt jeglicher Objektorientierung widersprechen.
Ich schreibe eigentlich ganz gern ein wenig mehr Code, wenn ich dadurch die Lesbarkeit erhöhe.
Du erhöhst die Lesbarkeit kein bisschen, GetInstance enhält absolut Null Information. WENN du deine GANZ WENIGEN globalen Instanzen UNBEDINGT in die Klasse packen willst (wofür es absolut keinen rationalen Grund gibt), wäre es das mindeste, die Konstruktion weiterer Instanzen trotzdem nicht zu verbieten, und die statischen Methoden sinnvoll zu benennen, beispielsweise Log::DefaultLog() etc. Dennoch solltest du freie Funktionen unbedingt mal probieren, eben aus genanntem Grund der einheitlichen Erweiterbarkeit, außerhalb der Klasse lassen sich gleichförmig beliebig viele weitere Instanzen anfügen, zudem erhälst du damit genannte Unabhängigkeit von Klassen und Objekten.
Das Pattern an sich findest du ja auch nicht von Grund auf falsch. Es wurde ja auch nicht umsonst entworfen. Wenn man für ein Singleton bessere Mittel hätte wie z.B. ein C++ Schlüsselwort wäre es sicher angenehmer und auch in manchen Situationen sinnvoll. Was die meisten doch eher stört, ist dass es sich einfach um eine globale Instanz in einer Klasse handelt.
Such doch bitte Mal nach einem einzigen Fall, in dem ein Singleton sinnvoll wäre. Du wirst sehen, praktisch alles lässt sich mit weniger oder gleichem Aufwand eleganter und funktioneller als normale konstruktionsunbeschränkte Klasse implementieren. Und nein, es stört nicht nur, dass es sich um eine globale Instanz handelt: es stört SOWOHL, dass es sich um eine globale Instanz handelt, ALS AUCH, dass weitere Instanzen verboten werden. Das Singleton bringt ZWEI BEDEUTENDE Nachteile in deine Software, und wenn es nicht einen absolut driftigen Grund dafür gibt, dass NUR GENAU EINE Instanz existieren DARF, ist es einfach nur falsch, diese beiden Nachteile einzugehen. Insofern wäre ein singleton-Schlüsselwort ein hinreichender Grund, eine Sprache grundsätzlich nicht einzusetzen.
In diesem Artikel wurde z.B. für eine Klasse ein zugehöriger namespace ála MyClassVars angelegt, in dem "globale" oder besser "namespace-lokale" Variablen extra außerhalb der Klasse angelegt wurden und das ganze hatte den positiven Effekt, dass die Kapselung höher war, als mit Membervariablen.
Sicher kannst du damit höhere Kapselung erreichen, aber das ist die letzte Art der Kapselung, die du willst. Dazu brauchst du allerhöchstens einen anonymen Namespace, und das was du erhälst, ist ein absolut starres Subsystem, von dem es wie beim Singleton nur exakt eine Instanz gibt, in dem du wie beim Singleton alle Probleme bzgl. globaler Abhängigkeiten, Multithreading, Testing etc. mitnimmst. Wenn dir Kapselung ein sehr sehr großes Anliegen wäre, wäre die richtige Lösung, einfach Zeiger und Referenzen auf vorwärts-deklarierte und übersetzungseinheitslokal definierte Strukturen an freie Funktionen rumzureichen.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von dot »

Cave Johnson, We're done here :)
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von BeRsErKeR »

CodingCat hat geschrieben:Es ist eigentlich alles gesagt. Es wäre nett, wenn du mal versuchen würdest, unsere Antworten zu verstehen, statt dich endlos in schwammigen Konterposts zu wiederholen. Dann würde dir auffallen, dass wir uns so oft wiederholen müssen, um deine vermischten Antworten immer wieder mühsam Punkt für Punkt zu korrigieren. WIR reden hier sehr wohl vom Singleton-MUSTER, und zwar solange, bis wir das Gefühl haben, dass du verstanden hast, worum es eigentlich geht.
Da ist wohl jemand mit dem falschen Fuß aufgestanden. :D

CodingCat hat geschrieben:
Man muss halt differenzieren ob man vom Singleton Pattern spricht oder von einer Singleton-Implementierung in C++ mit statischer Variable.
Nein, muss man nicht. Singleton heißt: NUR EINE INSTANZ. Globale Instanz heißt: GLOBALE ODER STATISCHE VARIABLE. Wenn du Singleton schreibst, heißt das, wir reden von Konstruktionsbeschränkung.
Du kannst ein Singleton auch implementieren ohne eine statische Instanz der Klasse anzulegen. Daher finde ich schon, dass man zwischen dem Pattern und der Implementierungsart unterscheiden muss, weil die Implementierung halt auf verschiedenem Wege erfolgen kann, z.B. wie gesagt ohne globale Instanz.

CodingCat hat geschrieben:
Betrifft meiner Meinung nach auch eher die C++ Implementierung und nicht das Pattern an sich.
Nein, das hat mit C++ absolut nichts zu tun, die Folgen von globalen Objekten/Variablen/Zuständen sind in allen Sprachen dieselben.
Wie gesagt kann man ein Singleton auf verschiedene Weisen implementieren und globale Objekte/Variablen sind dafür nicht zwangsweise nötig. Du scheinst aber davon auszugehen, dass Singleton immer verknüpft ist mit globaler Instanz. Einzigartig heißt aber nicht unbedingt auch global.

CodingCat hat geschrieben:
Ich schreibe eigentlich ganz gern ein wenig mehr Code, wenn ich dadurch die Lesbarkeit erhöhe.
Du erhöhst die Lesbarkeit kein bisschen, GetInstance enhält absolut Null Information. WENN du deine GANZ WENIGEN globalen Instanzen UNBEDINGT in die Klasse packen willst (wofür es absolut keinen rationalen Grund gibt), wäre es das mindeste, die Konstruktion weiterer Instanzen trotzdem nicht zu verbieten, und die statischen Methoden sinnvoll zu benennen, beispielsweise Log::DefaultLog() etc. Dennoch solltest du freie Funktionen unbedingt mal probieren, eben aus genanntem Grund der einheitlichen Erweiterbarkeit, außerhalb der Klasse lassen sich gleichförmig beliebig viele weitere Instanzen anfügen, zudem erhälst du damit genannte Unabhängigkeit von Klassen und Objekten.
Klar werde ich mir auch die hier genannten Ansätze angucken und vielleicht auch nutzen. Wie gesagt gibt es für mich aber einen rationalen Grund globale Instanzen in Klassen zu packen. Weil ich dann sofort erkenne, dass sie eine logische Zuordnung/Verbindung zu der Klasse hat. Das finde ich beispielsweise bei Konstanten sehr nützlich, die nur in der Klasse verwendet werden und einen Bezug zu ihr haben. Klar kann ich die Konstante auch außerhalb der Klasse anlegen, aber warum sollte irgendjemand anderes als diese eine Klasse überhaupt die Möglichkeit haben an diese Instanz heranzukommen? Ok das ist nun eher ein Beispiel mit privaten statischen Instanzen, aber es ist halt ein Beispiel.

CodingCat hat geschrieben:
Das Pattern an sich findest du ja auch nicht von Grund auf falsch. Es wurde ja auch nicht umsonst entworfen. Wenn man für ein Singleton bessere Mittel hätte wie z.B. ein C++ Schlüsselwort wäre es sicher angenehmer und auch in manchen Situationen sinnvoll. Was die meisten doch eher stört, ist dass es sich einfach um eine globale Instanz in einer Klasse handelt.
Such doch bitte Mal nach einem einzigen Fall, in dem ein Singleton sinnvoll wäre. Du wirst sehen, praktisch alles lässt sich mit weniger oder gleichem Aufwand eleganter und funktioneller als normale konstruktionsunbeschränkte Klasse implementieren. Und nein, es stört nicht nur, dass es sich um eine globale Instanz handelt: es stört SOWOHL, dass es sich um eine globale Instanz handelt, ALS AUCH, dass weitere Instanzen verboten werden. Das Singleton bringt ZWEI BEDEUTENDE Nachteile in deine Software, und wenn es nicht einen absolut driftigen Grund dafür gibt, dass NUR GENAU EINE Instanz existieren DARF, ist es einfach nur falsch, diese beiden Nachteile einzugehen. Insofern wäre ein singleton-Schlüsselwort ein hinreichender Grund, eine Sprache grundsätzlich nicht einzusetzen.
Das ist nun vielleicht weit hergeholt, aber nehmen wir mal an, es existiert ein Thread-Objekt, welches auch wirklich einen realen Thread repräsentiert in irgendeiner Weise. Das System unterstützt kein Multi-Threading und crasht wenn ein zweiter Thread gestartet wird oder schlimmer noch, überschreibt den alten. Wenn ich da nicht sicherstelle, dass nur ein Thread-Objekt gleichzeitig instanziiert wird, kann das recht übel enden. Wenn die ganze Initialisierung irgendwo drunter und schon vorm Inhalt des Konstruktors der Thread-Klasse passiert, kann ich da auch nicht mehr viel abfangen. Kurz gesagt, wenn ein System nicht unterstützt dass es gewisse Konstrukte mehrfach gibt, dann sollte es auch im Code sichergestellt werden, dass auf keinen Fall eine zweite Instanz existiert. Das wird in der Realität wohl kaum vorkommen, aber es wäre halt ein Anwendungsbeispiel.
Ohne Input kein Output.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von CodingCat »

BeRsErKeR hat geschrieben:Da ist wohl jemand mit dem falschen Fuß aufgestanden.
Nein, ich finde es schlicht unverschämt, wenn sorgfältig und umfassend formulierte Antworten mit hingeklatschten wirren Pseudoargumenten "widerlegt" werden sollen.
BeRsErKeR hat geschrieben:Wie gesagt kann man ein Singleton auf verschiedene Weisen implementieren und globale Objekte/Variablen sind dafür nicht zwangsweise nötig. Du scheinst aber davon auszugehen, dass Singleton immer verknüpft ist mit globaler Instanz. Einzigartig heißt aber nicht unbedingt auch global.
DU hast uns die ganze Zeit erzählt, dass es dir nur um die globale Instanz geht, NICHT ICH.
DU wirfst hier permanent Singletons und globale Instanzen durcheinander, und wenn wir das ganze mühsam auseinanderklamüsern, wirfst du UNS vor, die beiden zu vermischen?!
BeRsErKeR hat geschrieben:Ich nutze die Singleton-C++-Implementierung einfach wenn ich eine globale Instanz hübsch in einer Klasse verpacken will.
CodingCat hat geschrieben:Singleton heißt: NUR EINE INSTANZ. Globale Instanz heißt: GLOBALE ODER STATISCHE VARIABLE. Wenn du Singleton schreibst, heißt das, wir reden von Konstruktionsbeschränkung.
Da, schau, du musst nur lesen. ;)
BeRsErKeR hat geschrieben:Das wird in der Realität wohl kaum vorkommen, aber es wäre halt ein Anwendungsbeispiel.
Siehst du? Na endlich. :)
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von BeRsErKeR »

CodingCat hat geschrieben:
BeRsErKeR hat geschrieben:Da ist wohl jemand mit dem falschen Fuß aufgestanden.
Nein, ich finde es schlicht unverschämt, wenn sorgfältig und umfassend formulierte Antworten mit hingeklatschten wirren Pseudoargumenten "widerlegt" werden sollen.
Meine "Kritik" bezog sich weder auf die letzten Beiträge noch auf die sachliche Diskussion. Sie bezog sich auch nie auf dich. Das habe ich ja mehrfach versucht dir klar zu machen. Und ich habe auch nie behauptet, dass alle eure Argumente falsch oder unsachlich sind. Es gab halt einige Beiträge (vorallem auf den ersten Seiten), die ich zu extrem negativ fand. Es geht mir nicht darum wer Recht hat, sondern einfach, dass ich mir bei manchen Beiträgen (das muss keiner von dir sein) mehr Objektivität wünschen würde. Ich wollte eigentlich auch nicht eine neuerliche Diskussion anfangen. Leider ist genau das passiert.

CodingCat hat geschrieben:
BeRsErKeR hat geschrieben:Wie gesagt kann man ein Singleton auf verschiedene Weisen implementieren und globale Objekte/Variablen sind dafür nicht zwangsweise nötig. Du scheinst aber davon auszugehen, dass Singleton immer verknüpft ist mit globaler Instanz. Einzigartig heißt aber nicht unbedingt auch global.
DU hast uns die ganze Zeit erzählt, dass es dir nur um die globale Instanz geht, NICHT ICH.
DU wirfst hier permanent Singletons und globale Instanzen durcheinander, und wenn wir das ganze mühsam auseinanderklamüsern, wirfst du UNS vor, die beiden zu vermischen?!
Ich habe extra betont, dass ich nicht vom Pattern sprach, sondern von der Implementierung mit statischer Variable. Ich habe sogar angemerkt, dass mir egal ist wozu ein Singleton entworfen wurde, wenn diese Implementierung (auch wenn das nichts mit Singleton zu tun hat, aber diese eine Implementierung hat einfach die Form) für mich angenehm ist. Wir müssen uns doch gar nicht darum streiten, ob ein Singleton supertoll ist oder nicht. Darum geht es mir hier gar nicht.

CodingCat hat geschrieben:
BeRsErKeR hat geschrieben:Ich nutze die Singleton-C++-Implementierung einfach wenn ich eine globale Instanz hübsch in einer Klasse verpacken will.
CodingCat hat geschrieben:Singleton heißt: NUR EINE INSTANZ. Globale Instanz heißt: GLOBALE ODER STATISCHE VARIABLE. Wenn du Singleton schreibst, heißt das, wir reden von Konstruktionsbeschränkung.
Da, schau, du musst nur lesen. ;)
BeRsErKeR hat geschrieben:Das wird in der Realität wohl kaum vorkommen, aber es wäre halt ein Anwendungsbeispiel.
Siehst du? Na endlich. :)
Nur weil ich kein konkretes Beispiel kenne und du auch nicht, heißt das noch lange nichts. Aber egal. Diese Diskussion geht schon viel zu lange und führt nirgendwo hin. Ich hab das Gefühl dass wir einfach aneinander vorbei geredet haben, von daher sollten wir hier vielleicht einfach einen Cut machen. Das Wesentliche um das es in diesem Thread eigentlich mal ging, wurde ja schon zu Genüge gesagt.


Von daher. Lassen wir das.
Ohne Input kein Output.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von CodingCat »

BeRsErKeR hat geschrieben:Meine "Kritik" bezog sich weder auf die letzten Beiträge noch auf die sachliche Diskussion. Sie bezog sich auch nie auf dich. Das habe ich ja mehrfach versucht dir klar zu machen. Und ich habe auch nie behauptet, dass alle eure Argumente falsch oder unsachlich sind.
Meine Kritik bezog sich aber sehr wohl auf dich. Wenn du nur die Diskussionsweise kritisieren wolltest, hättest du dich darauf eben auch beschränken müssen. Solange du zusätzlich auf Sachebene versuchst, mit Bauchgefühl dagegen zu argumentieren, und dabei themenrelevante Dinge durcheinander bringst, müssen wir irgendwie korrigierend eingreifen. Für dich mag das egal sein, für andere Leser ist es das nicht.
BeRsErKeR hat geschrieben:Diese Diskussion geht schon viel zu lange und führt nirgendwo hin.
Oh doch, ich habe den Eindruck, dass wir hier sehr weit gekommen sind.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von BeRsErKeR »

Sorry dass ich das nochmal auskrame, aber wollte keinen neuen Thread aufmachen.

Ich hätte da mal eine Frage zur Lebenszeit von statischen Membervariablen, rein aus Interesse.

Leben statische Member länger als die globale Klasseninstanzen, die diese enthalten? Also gibt es da eine klare Festlegung?

Beispiel:

Code: Alles auswählen

class foo
{
public:
    ~foo() { printf("%d\n", bar);

private:
    static int bar;
};

foo f; // von mir aus auch static foo f;

Ist in diesem Beispiel gewährleistet, dass bar noch existiert, wenn f zerstört wird?

Ein int ist vielleicht kein gutes Beispiel. bar könnte auch eine Instanz einer anderen Klasse sein, etc.
Ohne Input kein Output.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von dot »

Statische Member haben static storage duration, leben also vom Programmstart bis zum Programmende. Trotzdem sollte man mit sowas sehr vorsichtig sein. Meiner Erfahrung nach braucht man statische Member eigentlich praktisch nie.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von BeRsErKeR »

Das was du sagst ist mir klar, darum sagte ich ja, ich frage aus Interesse. Beantwortet wurde meine Frage nun nicht direkt. Die Klasseninstanz lebt ja auch bis zum "Programmende", aber ist dann die statische Membervariable noch existent?
Ohne Input kein Output.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von CodingCat »

Alle Instanzen werden grunsätzlich in umgekehrter Konstruktionsabschlussreihenfolge zerstört.
C++11 hat geschrieben:Non-local variables with thread storage duration are initialized as a consequence of thread execution.
[...]
Definitions of explicitly specialized class template static data members have ordered initialization. Other class template static data members (i.e., implicitly or explicitly instantiated specializations) have unordered initialization. Other non-local variables with static storage duration have ordered initialization.
[...]
Variables with ordered initialization defined within a single translation unit shall be initialized in the order of their definitions in the translation unit.
Die Konstruktionsreihenfolge INNERHALB EINER ÜBERSETZUNGSEINHEIT entspricht also der Definitionsreihenfolge. Über mehrere Übersetzungseinheiten hinweg ist die Reihenfolge hingegen undefiniert.

In deinem Beispiel lässt sich keine Aussage machen, weil dein static Member bar dort nur deklariert, jedoch nirgends definiert wurde.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von BeRsErKeR »

Sprich es wäre sinnvoll die statischen Member sofort nach der Klasse zu initialisieren? Danke erstmal für die Antwort.
Ohne Input kein Output.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von CodingCat »

Ja, wenn bar zur Zerstörung von foo noch existieren soll, muss es vor vollendeter Konstruktion von foo vollständig konstruiert und somit vor foo definiert worden sein. Initialisierung ist dabei möglich, aber nicht notwendig. Die explizite Definition außerhalb der Klasse, ob mit oder ohne Initialisierung, ist jedoch auf jeden Fall notwendig.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von BeRsErKeR »

Wie verhält es sich wenn ich den Code in zwei verschiedene Ausführungseinheiten inkludiere? Dann wär mir die Definition im Header doch ein Stein im Weg oder? Weil es die Definition/Initialisierung in zwei verschiedenen Ausführungseinheiten gäbe. Oder irre ich mich da?
Ohne Input kein Output.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von dot »

BeRsErKeR hat geschrieben:Wie verhält es sich wenn ich den Code in zwei verschiedene Ausführungseinheiten inkludiere? Dann wär mir die Definition im Header doch ein Stein im Weg oder? Weil es die Definition/Initialisierung in zwei verschiedenen Ausführungseinheiten gäbe. Oder irre ich mich da?
Definierst du deine statischen Member im Header? Das solltest du auf keinen Fall tun. Wenn was zweimal definiert wird, gibts natürlich wie immer Linkerfehler...
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von CodingCat »

Richtig, die Definition darf immer nur in einer Übersetzungseinheit vorkommen. In allen anderen Übersetzungseinheiten kann die Variable dann genutzt werden, der Initialisierungszeitpunkt ist dort jedoch nicht mehr klar. Aus diesem Grund vermeidet man komplexe Abhängigkeiten statischer Members und globaler Variablen auch in der Regel. Wenn du unbedingt eine bestimmte statische Initialisierungsreihenfolge brauchst, hilft eigentlich nur die Methoden-lokale Definition statischer Variablen, was jedoch bei jedem Zugriff einen gewissen Runtime-Overhead bedeutet.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von dot »

Wobei ich, wie gesagt, sowieso einen grooooßen Bogen um statische Member machen würde. Speziell in Zeiten von Multicore CPUs ist sowas imo eigentlich rein prinzipiell schon pures Gift...
CrystalCoder
Beiträge: 54
Registriert: 03.03.2002, 17:51
Kontaktdaten:

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von CrystalCoder »

Mich würde mal eure Meinung dazu interessieren, ein Singleton dazu zu benutzen, um mehrere Klassen zu einem großen Objekt, wie zum Beispiel einer kompletten Game Engine zu gruppieren.
Mike McShaffrey setzt in seinem Buch "Game Coding Complete" ein Singleton für exakt diesen Zweck ein Singleton ein, welches (nicht statische) Objektinstanzen von global benötigten Komponenten wie einem Ressourcen Manager, Spiellogik, Actor Management usw. verbindet.
Dabei geht es nicht darum alle Komponenten global verfügbar zu machen, dazu würde ein einfaches globale Objekt der "Gruppierungsklasse" ausreichen. Vielmehr geht es darum zu suggerieren, dass sich die gesamte Applikation so aufbaut, dass sich alles innerhalb dieses einen Objekts abspielt und deswegen nur eine Instanz existieren darf (will man mehrere Spiele damit entwickeln, so soll man das in getrennten Projekten machen).

Die Game Engine ist dann Baumartig strukturiert (mit dem Singleton als Root), dass alle Module in die einzelnen Komponenten "gesteckt" werden können und diese sich vollautomatisch initialisieren und freigeben (natürlich müssen die Module dazu ihre eigenen Initialisierungs- und Freigaberoutinen implementiert haben basierend auf den vorgegebenen Interfaces, aber diese werden dann automatisch aufgerufen und organisiert).
Man hat damit ein riesiges Objekt, welches man mitsamt aller zugehörigen (nicht singleton) Klassen in eine lib stecken könnte (wenn man will). Dann holt man sich die Instanz davon und füllt die Game Engine darüber mit Daten (Events, Ressourcen, GameLogic, Actors/Viewers, AI, Scripts, etc).
Mir persönlich gefällt das sehr gut wie das Singleton Pattern hier eingesetzt wird. Ich selbst bin jedenfalls kein Freund von globalen Variablen (mir gefällt das sehr gut, wenn ich irgendwo ClassName::getInstance() sehe weil ich dann exakt weiß um was es sich handelt auch wenn ich nicht gerade meinen Code lese. Bei globalen Variablen ist das - zumindest bei fremden Codes - oft nicht (immer) so offensichtlich).
Das soll jetzt nicht heißen dass ich für alles mögliche gleich ein Singleton nehmen würde (oben genanntes Beispiel und evtl für ein zentrales Loggingsystem mal abgesehen). Eher würde ich alles lokal in der main-Function deklarieren/definieren und per pointer/referenz übergeben.

Dennoch finde ich das in dem Buch sehr schön gelöst und würde es wohl übernehmen wollen.
Was sagt ihr dazu?
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von dot »

Imo jetzt nicht gerade eine so tolle Idee. Wofür braucht man da unbedingt ein Singleton? Und wenn man kein Singleton braucht, wieso macht man dann eins? Wie praktisch immer: Das einzige was man damit erreicht sind unnötige Einschränkungen. Abgesehen davon halte ich das Konzept von "global benötigten Komponenten" schon von vornherein für einen Irrtum.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von Krishty »

Erreicht die MFC nicht genau so ein Verhalten, indem eine globale Instanz der Programmklasse angelegt wird? Der Leben beginnt mit dem Programmstart; sie wird durch die WinMain() mit Nachrichten versorgt; ihr Leben endet schließlich mit Programmende und dazwischen ist sie immer überall verfügbar.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von dot »

Naja, die MFC würd ich jetzt nicht grad als Vorbild für gutes Design sehen...
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von Krishty »

Niemals; aber es zeigt, dass es auch ohne Singleton geht.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von dot »

Achso. Ja, es geht immer ohne Singleton. Es geht nicht nur, es ist auch besser ;)
CrystalCoder
Beiträge: 54
Registriert: 03.03.2002, 17:51
Kontaktdaten:

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von CrystalCoder »

Sinn macht es schon, damit nicht jede Komponente eine Referenz auf das Objekt braucht, wenn die Komponenten abhängig voneinander arbeiten sollen (und wenn ich die Wahl zwischen Objekt als globale Variable und einem Singleton hab, dann ist mir die Singleton Variante eigentlich lieber).
Das ganze als Singleton zu machen hat auch nicht weiter größere Nachteile (jedenfalls fällt mir grad nichts ein was mich in diesem Fall am Design einschränkt).
Ok das wird in dem Buch den Lesern so präsentiert und ist wohl auch etwas anschaulicher wenn man sagt: "Das ist das Zentrum unserer Applikation und es darf deswegen unter allen Umständen nur eine Instanz geben".
Jedenfalls lieber so, als dass noch jemand auf die Idee kommt das zu verwechseln (z.B. wenn man Spielmodi oder GameStates in jeweils eigene App-Objekte packen will).

Das als Singleton zu machen ist an sich ja eigentlich nicht unbedingt nötig, aber hilfreich, wenn man nach außen hin ausdrücken will, dass es zu jeder Zeit nur eine Instanz geben darf und diese über die gesamte Programmlaufzeit ab der ersten Verwendung immer verfügbar sein muss.
Für so ziemlich alles gibt es unterschiedliche Lösungsansätze. Wem etwas nicht gefällt, dann soll er es nicht so machen, aber "unsauber" ist das ja auch nicht (es sei denn jemand kann mir für diese spezielle Anwendung schwerwiegende Probleme aufzeigen, bei welchen eine globale Objektvariable Abhilfe schaffen könnte).
Ich sehe nur, dass man die Kommunikation zwischen den Komponenten innerhalb des Objektes stark vereinfachen kann und der Code weiterhin gut lesbar bleibt. So könnte man eine Instanz auf das Loggingsystem innerhalb dieses statischen Objektes halten und jede andere Komponente kann ohne weiteres Zutun damit arbeiten.
Es ist auch dann praktisch, wenn eine zusätzliche Komponente hinzukommt, die von da an auch von anderen Komponenten genutzt werden soll, so muss man an der Klassendefinition der anderen Komponenten nichts ändern und kann innerhalb der Komponentenmethoden einfach auf diese neue Komponente zugreifen. Das würde zwar auch mit einer globalen Objektariablen gehen aber sowas wie einfach nur ein Variablenzugriff in einer Methode, wo es kein Parameter und keine Lokale ist, sehe ich nicht so gerne (Objekteigenschaften rufe ich immer mit this-> auf).

Naja jedem das seine :)
Wollte ja nur mal eure Meinung dazu hören, das war jetzt keine Rechtfertigung sondern mehr eine Begründung warum mir das so besser gefällt.
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von Chromanoid »

Stell dir vor du machst einen Editor für dein Spiel. Dieser Editor soll dann mehrere Instanzen des Spiels direkt erstellen und ansprechen können. Da kann ein Singleton schon hinderlich werden. Singletons sind vielleicht auch ein bisschen was für faule/pragmatische Entwickler, die sich keine Sorgen über Nebeneffekte machen wollen. Da man ja ein Singleton benutzt, kann man auf Kosten von Flexibilität viele Konstellationen einfach ausschließen.
Das von dir beschriebene Singleton für die Modul-Konfiguration ist ja im Grunde nur die Kapselung einiger Funktionen, die man sonst evt. direkt in der main-Funktion erledigen würde. Wenn man es dann schon kapselt, würde eine Variante ohne Singleton doch einen viel höheren Mehrwert bedeuten.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von dot »

CrystalCoder hat geschrieben:Sinn macht es schon, damit nicht jede Komponente eine Referenz auf das Objekt braucht, wenn die Komponenten abhängig voneinander arbeiten sollen (und wenn ich die Wahl zwischen Objekt als globale Variable und einem Singleton hab, dann ist mir die Singleton Variante eigentlich lieber).
Simmt. Denn anstatt die Abhängigkeiten explizit im Code zu haben, sind die dann schön versteckt, sodass sie erst auffallen, wenn der Singleton zum Problem wird, sodass du ihn dann mühsam herausoperieren darfst. Abgesehen davon sind Singleton und globale Variablen zwei völlig orthogonale Dinge. Singleton ist kein Ersatz für eine globale Variable und auch nicht umgekehrt. Die beiden Dinge haben absolut nichts miteinander zu tun. Ich empfehle, den ganzen Thread hier mal aufmerksam zu lesen, wir haben das imo wirklich schon zur Genüge diskutiert ;)
CrystalCoder hat geschrieben:Das ganze als Singleton zu machen hat auch nicht weiter größere Nachteile (jedenfalls fällt mir grad nichts ein was mich in diesem Fall am Design einschränkt).
Es hat Nachteile ohne einen Vorteil zu bieten.
CrystalCoder hat geschrieben:"Das ist das Zentrum unserer Applikation und es darf deswegen unter allen Umständen nur eine Instanz geben".
"Meine Wohnung ist das Zentrum meines täglichen Lebens. Darum darf es in meinem Leben um jeden Preis bis ans Ende aller Tage nur eine Wohnung haben." Das ist eine Argumentation, die ich nicht nachvollziehen kann.
CrystalCoder hat geschrieben:Das als Singleton zu machen ist an sich ja eigentlich nicht unbedingt nötig, aber hilfreich, wenn man nach außen hin ausdrücken will, dass es zu jeder Zeit nur eine Instanz geben darf und diese über die gesamte Programmlaufzeit ab der ersten Verwendung immer verfügbar sein muss.
Wenn man das will. Aber warum sollte man das hier wollen?
CrystalCoder hat geschrieben:Wem etwas nicht gefällt, dann soll er es nicht so machen, aber "unsauber" ist das ja auch nicht (es sei denn jemand kann mir für diese spezielle Anwendung schwerwiegende Probleme aufzeigen, bei welchen eine globale Objektvariable Abhilfe schaffen könnte).
Wer sagt, dass eine globale Variable die Alternative ist?
CrystalCoder hat geschrieben:Ich sehe nur, dass man die Kommunikation zwischen den Komponenten innerhalb des Objektes stark vereinfachen kann und der Code weiterhin gut lesbar bleibt. So könnte man eine Instanz auf das Loggingsystem innerhalb dieses statischen Objektes halten und jede andere Komponente kann ohne weiteres Zutun damit arbeiten.
Und eines Tages will man, dass eine Komponente in ein andres Log logged als der Rest. Gute Nacht.
CrystalCoder hat geschrieben:Es ist auch dann praktisch [...]
Exakt, es ist praktisch (oder sagen wir besser: bequem). Und zwar genau so lange, bis man merkt wie unpraktisch es eigentlich ist ;)
waigie
Beiträge: 82
Registriert: 20.05.2009, 19:37

Re: [C++] Speicherfreigabe bei statischem Singleton

Beitrag von waigie »

So ganz verstehe ich aber nicht wieso ein Singelton jetzt die Übersicht steigert. Du holst dir die Instanz mit ClassName::getInstance() und weist daher um was es sich handelt. Das liegt aber nur daran das sich jeder bei Singletons an diese Namenkonvention hält. Man könnte genauso gut ClassName::foo() nutzen um an die Instanz zu kommen. Genauso ist es mit Globalen Variablen. Ich kann die globale Variable global_className_instance nennen oder eben bar. Bei dem einen weiß ich genau worum es sich handelt beim anderen nicht.
Das soll jetzt aber nicht bedeuten das ich eine globale Variable vorziehen würde. Dot und CodingCat haben mich in einer langen Diskussion davon überzeugen können, das Singletons eigentlich immer Fehl am Platz sind.

So alles andere gegen deine Idee ist gesagt wollte nur wissen wo die globale Variable schlimmer wäre?
Antworten