B
DStefan schrieb:
Ziemlich unnatürlich finde ich hingegen deine Definition dieses Foo-Objekts, das nichts weiter macht als aufräumen. Wenn man schon mal soweit ist, warum nicht alles in eine Klasse packen?
Wegen der 15 Gründe als meinem vorherigen Post? Der Punkt ist der, dass ich noch kein einziges Argument für die Verwendung der Klassenkrücke gesehen habe. Du schwächste mit mehr oder weniger Erfolg meine Argumente ab. Entkräftete wird wird aber keins. Die einzig logische Schlussfolgerung ist diese Krücke nicht zu verwenden.
DStefan schrieb:
Die Verwendung von init() und destroy() für ein Singleton hat den großen Nachteil, dass man es explizit machen muss. Vergisst das jemand in main(), kann es Probleme geben. Verwendet man Ctor und Dtor, gibt es diese Probleme nicht.
Ctor und Dtor funktionieren nur falls sämtliche Interaktion zwischen den Singletons nur innerhalb der main Funktion (oder von da aufgerufenen Funktionen) stattfindet. Wenn das nicht der Fall ist geht der Dtor Ansatz nicht wie du bereits selbst gezeigt hast.
DStefan schrieb:
Das Problem wird allerdings nicht gelöst, wenn man in main() destroy() aufruft, weil nämlich auch nach Beendigung von main() noch Code ausgeführt wird, und dieser Code kann versuchen, das Singleton zu verwenden, nachdem es bereits abgebaut wurde.
Hausaufgabe 1: Überlege dir warum du hier versuchst ein Nonproblem zu lösen. (Tipp: Wir mischen keine Singletontypen)
Hausaufgabe 2: Überlege dir wie man selbst beim Mischen verschiedener Singletontypen und nicht zyklischer Interaktionen das "Problem" löst. (Tipp: Referenzzählung)
DStefan schrieb:
Wenn ich irgend etwas so programmiere, wie du es vorschlägst, kann ich vermutlich Compile-Zeit sparen.
und Entwickelungszeit da der Code dem KISS-Prinzip folgt, Hirnschmalz beim verstehen dieser Klassenkrücken und ein klein wenig Laufzeit.
DStefan schrieb:
Aber wollen wir hier wirklich über die Vor- und Nachteile objektorientierter Programmierung reden?
Bleibt mal beim konkreten Fall.
DStefan schrieb:
Kein Header ist von sich aus selbstdokumentierend, keine Technik sorgt von sich aus für mehr (oder eben weniger) Übersicht.
Also wenn ich
#ifndef RANDOM_NUMBER_GENERATOR_HPP
#define RANDOM_NUMBER_GENERATOR_HPP
namespace random{
void seed(int n);
int roll();
}
#endif
lese, dann kann ich mir die Doku sparen.
DStefan schrieb:
Auch Klassen verursachen nicht mehr oder weniger "Rauschen", als eine Sammlung von Funktionen in einem Namespace. Rauschen verursacht oder vermeidet der Entwickler.
Dann übersetzt mein Beispiel oben mal in eine korrekte Klassenkrücke, ohne dass mind. 50% deiner Codes 0 nützliche Informationen an den Benutzer liefert.
DStefan schrieb:
Deine Behauptung, man erhalte eine ABI-unabhängige Schnittstelle ist mE falsch. Der Namespace geht mit in das Name Mangling ein und das Ergebnis ist keine C-Schnittstelle. Jedenfalls machen das meine Compiler so - und ich glaube, sie müssen das auch machen.
Du wirst doch noch fähig sein ein extern "C"{ ... } drum rum zu packen, wenn du das wirklich brauchst. Der Punkt ist, du musst 12 Zeichen einfügen um etwas zu erreichen, was bei der Klassenkrücke nur mit großen Mühen vielleicht machbar ist.
Eine mögliche Arbeitseinsparung mit deiner Vorgehensweise ist doch kaum der Rede wert. Selbst wenn ich ein einfaches Singleton komplett von Hand schreibe, benötige ich für die Infrastruktur (also den Singleton-Code im engeren Sinne) kaum eine viertel Stunde.
Ich hab für den Code oben nicht mal eine Minute gebraucht. Für eine korrekte Klassenkrücke bräuchte ich wohl etwa 10 Minuten. Das sind 90% der Zeit gespart und viele Möglichkeiten weniger Bugs einzubauen.
In diesem Sinne ist deine Version auch nicht simpler zu schreiben. Aber sie ist schwieriger zu verwenden. Denke nur an init() und destroy().
Dass du auch auf die Ctor- und Dtorschiene mit all ihren Problemen aufspringen kannst habe ich bereits gezeigt. Ansonsten ist die syntaktische Verwendung bis aufs letzte Zeichen gleich und kann deswegen gar nicht schwieriger sein. Du kreidest hier an, dass man init() und destroy() verwenden kann und somit ein sauberes Shutdown realisieren kann.
Ich glaube nicht, dass der nicht vorhandene this-Pointer dem Compiler ermöglicht "besseren" Code zu erzeugen.
Sollen wir wetten, dass da ein Parameter weniger auf dem Stack oder in einem Register übergeben wird?
deren Methoden größtenteils inline sind
Sind sie aber nicht, siehe Ursprungspost.
Ein Witzbold, der von meinem Singleton ableitet, weiß entweder, was er tut oder er kann mir gestolen bleiben. Das ist doch kein Argument gegen die Verwendung von Klassen.
Natürlich ist es eins. Ein sehr schwaches aber es ist ein Argument.
Andererseits könnte ich aber Ableitungen ermöglichen - aus welchem Grund auch immer - oder sogar den Einsatz einer Unterklasse bei der Verwendung des Singletons, etwa über eine Factory.
Wat?Ich kann dir da nicht folgen. Denk dein Argument noch mal durch und überlege dir, ob es dann auch wirklich nur max. 1 Objekt gibt. Ich würde so weit gehen zu sagen, dass von einem Singletonableiten immer Blödsinn ist. Begründung:
* Es gibt eine global zugängliche Instanz der Basisklasse.
* Es darf maximal eine Instanz der Basisklasse geben.
* Jede abgeleitete Klasse erzeugt bei der Instantiierung eine Instanz der Basisklasse.
=> Die abgeleitete Klasse darf nie instantiiert werden.
=> Sie ist Blödsinn.