Verschoben nach Allgemein: Hilfreicher Inhalt, der auch durchaus durch Suchmaschinen findbar sein sollte Hi,
ich habe in meinem Framework eine Klasse "CISystem" welche die ganzen System geschichten kapselt und logischerweise auf jedem System verschieden ist.
Bisher habe ich es so gemacht, das JEDE Funktion von CISystem static ist, so kann ich z.B. im Code dann einfach:
CISystem::getNumMonitors();
aufrufen.
Jetzt unterstütze ich aber mittlerweile 5 Verschiedene Systeme (und es werden sicher noch mehr) - und das erhöht den Aufwand ziemlich wenn ich was an der System klasse ändere.. denn wenn ich z.B. ein "CISystem::doSomething()" unter dem Mac-System einführe, muß ich es gleichzeitig auch in den anderen Systemen einpflegen, obwohl es diese funktion dort evtl garnicht gibt - sie also immer 0 oder einen default wert zurück liefert.
Also hab ich vor das ganze weg von statischen methoden, hin zu einer normalen Klasse mit überladenen funktionen zu wandeln.
Es gibt dann eben ein CISystemBase von dem alle anderen sich ableitien und nur das überschreiben was sie brauchen/wollen.
Soweit kein Problem.
Was mich an der sache exterm stört ist, das die schöne, übersichtliche schreibweise wegwäre und das neue in etwa so aussähe:
CISystem::getSystem().getNumMonitors();
Gut, das ist jetzt auch nicht das schlimmste, aber irgendwie doppelt gemoppelt.. daher die frage, wie bekomm ich das eleganter hin??
eine globale Function getSystem() fände ich auch nicht so elegant.
Hat jemand eine Idee wie man das hübscher hinbekommt?
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Gehts dir rein um die Optik, den Schreibaufwand oder eventuelle Performance-Themen?
Bei Java gibts auch sowas: System.out.println(). Das zu tippen nervt. Deshalb verwende ich die IDE Template unterstützung. So braucht man nur sysout + Autovervollständigung tippen und fertig.
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Wie machst du es denn bisher z.B. bei getNumMonitors? Fragst du in der Funktion das System ab oder arbeitetest du mit Compilerdirektiven?
Mit diesen dürfte das ganze doch recht schön und einfach umsetzbar sein.
Oder du hast eine CINullSystemklasse, die bei jeder Methode immer 0 zurückliefert aber alle Funktionen erstmal definiert. Dann hast du z.B. eine CIWindowsSytem.h (oder ähnlich), eine CIMacSystem.h usw., wobei jede dieser Headerfiles stets die gleiche Kindklasse CISystem definiert, weshalb zwei Headerdateien auch nichts gleichzeitig nutzbar wären, und du bindest per Compilerdirektive (dabei nur an einer Stelle und nicht überall) immer die richtige ein (oder erstellst eine identische Kindklasse, falls du das System noch gar nicht untersützt).
LG Ziz
_________________ Denn wer nur schweigt, weil er Konflikte scheut, der macht Sachen, die er hinterher bereut. Und das ist verkehrt, denn es ist nicht so schwer, jeden Tag zu tun als ob's der letzte wär’. Und du schaust mich an und fragst ob ich das kann. Und ich denk, ich werd' mich ändern irgendwann. _________________Farin Urlaub - Bewegungslos
ich hab drei Vorschläge, zwei davon sind aber nur detailliertere Ausführungen des bisher gesagten.
#1 Kennt C++ static imports? Bei Java kann man statische Methoden so in andere Dateien importieren, dass man nichtmehr die Klasse davorschreiben muss. Das würde also aus sowas:
Code:
class CISystem { public static int getNumMonitors() { ... } }
[...]
import stuff.CISystem;
int numberOfMonitors = CISystem.getNumMonitors();
Sowas machen:
Code:
import static stuff.CISystem.getNumMonitors;
int numberOfMonitors = getNumMonitors();
Wenn C++ sowas kann, könntest du doch einfach das "getInstance()" (was ja statisch ist), in z.B. "environment()" umbenennen und könntest im Code dann:
Code:
environment().getNumMonitors();
schreiben
#2 prinzipiell schreit das, was du möchtest, tatsächlich nach einem Interface (oder in deinem Fall einer abstrakten Oberklasse) und verschiedenen, konkreten Implementierungen. Und dann bräuchtest du natürlich irgendwo eine Instanzvariable. Die musst du ja nicht zwingend mit "getInstance()" erreichbar machen, kannst ja auch was schöneres nehmen
z.B. Application::environment->getNumMonitors()
wobei environment einfach ein public static field von Application ist, in welches ganz zu Beginn die konkrete Implementierung reingesteckt wird... environment = new MacEnvironment();
so in der Art Ist vielleicht etwas hübscher als CISystem::getInstance()->getNumMonitors();
#3 Oder du machst es so wie Ziz und wie es die Java Runtime macht. Dort hast du kein explizites "Interface" oder ne abstrakte Klasse... Sondern im Endeffekt durch den Preprocessor verschiedene Implementierungen und für den Code sieht es so aus, als gäbe es nur eine. Bei Java wären das die verschiedenen Java Runtimes für die Plattformen. Dagegen spricht vor allem deshalb nichts, weil du das ja nicht zur Laufzeit austauschen können musst.
Tellerrand: Das ist übrigens einer der Bereiche, wo Scala glänzt. Dort gibt es neben Klassen auch Objekte, die man so hindeklarieren kann. Die funktionieren dann im Endeffekt wie Singletons, werden aber ohne ein getInstance() angesprochen
Grüße, ~ Frase
P.S.: Was macht das überhaupt im Offtopic? Wär das nicht eher was für Allgemein?
_________________ "Für kein Tier wird so viel gearbeitet wie für die Katz'."
Das hat den Vorteil das du das lokal dann so nennen kannst wie du es gerade haben willst. Z.B. ist es ja dann kein Problem wenn die Variable einfach nur "k" heißt.
Wird das Singleton an einer Stelle häufig genutzt legt ich meistens auch ein Klasseanttribut an und initialisiere das nur einmal im Konstruktor der jeweiligen Klasse.
#5 Wenn du ein Fan von Markos bist könntest du auch ein Marko definieren. Etwa so:
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2623 Wohnort: Berlin
Programmiersprache: Go, C/C++
Von Interfaces rate ich dir ab, da hab ich schmerzhafte Erfahrungen gemacht, da ja ein Interface virtuelle methoden nutzt, werden runtime checks eingeführt und es gibt extra functions calls, pro ableitung und noch den mehraufwand der rtti. Das drückt die Performance spürbar, wenn man solch eine Methode in einer Echtzeitanwendung immer wieder aufruft. http://www.gamedev.net/reference/programming/features/AbsPolyOpt/ Hier gibs auch ein guten Artikel zu dem Problem.
Das verpacken in ein Makro ist auch meine Empfehlung, das mach ich genauso. Z.B. #define Console RadonFramework::IO::Console::GetInstance() oder #define LogInfo(X) RadonFramework::IO::Log::GetInstance().Add(X,RadonFramework::IO::Log::InfoChannel,__LINE__,__FILE__) Damit erzielst du auch den gleichen Effekt wie das von Frase angesprochende Scala Feature, dass man Klasse.Methode() machen kann und nicht erst eine Instanz erstellen muss. Dieses Features gibt es übrigens auch in C#.
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Mitglieder in diesem Forum: 0 Mitglieder und 13 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.