Zugriff auf private Elemente
-
Hallo allesamt,
folgendes (umfangreiches) Problem: Ich habe, um das Ganze zu vereinfachen, drei Klassen:
Klasse A) enthält wichtige Methoden/Routinen zur Aussteuerung eines Systems. Man könnte sie als "Core" des Programms ansehen.
Klass
ist eine Basisklasse die als Schnittstelle zwischen verschiedenen Librareis dient und beinhaltet nur pure virtual Methoden.Klasse C) erbt von dieser Basisklasse und definiert die jeweiligen Methoden aus.
Anzumerken ist, dass KLASSE A UND C SINGLETONS SIND, und JEDE KLASSE IN EINER EIGENEN LIBRARY STECKT. Hier kurz simpler Code zu den drei Klassen (Definition der Methoden sind hier der Einfachheit halber inline):
Klasse A, Library A (CoreKlasse):
class CClassA : public Singleton<CClassA> { public: void MachWasA(void){}; CClassA(void){}; ~CClassA(void){}; };Klasse B, Library B (BasisKlasse/Interface):
template <class T> class CClassB : public Singleton<T> { public: virtual void MachWasB(void) = 0; CClassB(void){}; ~CClassB(void){}; };Klasse C, Library C (Irgendeine andere Klasse):
class CClassC : public CClassB<CClassC> { public: void MachWasB(void){}; CClassC(void){}; ~CClassC(void){}; };Library C (und damit auch CClassC) werden zu dem Hauptprogramm dynamisch zur Laufzeit dazugelinkt, das funktioniert auch alles einwandfrei. Für die Interessierten: Es entscheidet sich erst zur Laufzeit welche Lib mit welcher Funktionalität wirklich gebraucht wird. Klasse B ist praktisch die Schnittstelle die überall eingebunden wird. Klasse A und C "wissen voneinender nix", ums so auszudrücken.
Das blöde ist jedoch, dass Klasse A bestimmte Membervariablen aus Klasse C abfragen muss (vice versa), also habe ich micht entschlossen genau diese Member aus der Klassendefinition zu entfernen, und das alles in einer weiteren "globalen" CFG-Klasse zu hinterlegen, die ebenfalls überall fest mit eingbunden wird (Ich hoffe man kann mir noch folgen ^^):
#define Cfg CCfg::getInstance() // Für Singleton-Instanz class CCfg_ClassC { private: bool bTestflag; public: bool getTestFlag(){return this->bTestflag;}; CCfg_ClassC(){}; ~CCfg_ClassC(){}; }; class CCfg : public Singleton<CCfg> { public: CCfg_ClassC ConfigFuerC; CCfg (void){}; ~CCfg (void){}; };Soooooo, jetzt würde ich in Klasse A ne Methode machen, mit folgendem Code:
void CClassA::MachWasA(void) { if(Cfg->ConfigFuerC.getTestflag()) fprintf(stdout, "Hooray!\n"); else fprintf(stdout, "Och menno...\n"); }Soweit funktioniert's auch einwandfrei. Mein Problem ist jetzt nur das Verändern des Wertes von "bTestflag". Klasse C soll die einzige sein, die darauf zugreifen kann, bzw. jede, die von Klasse B erbt, aber da der Member protected ist, geht das nicht. Eine Friend-Deklaration für Klasse B zu machen geht auch net, da die nicht an die Kinder weitergegeben werden. Bei C# könnte man prüfen ob ein bestimmtes Interface in der Klasse implementiert wurde - meines Wissens gibt's das in C++ leider nicht

Hat irgendjemand irgendeine Idee? Vermutlich isses was total banales und ich denk nur wieder zu kompliziert... Auch völlig andere Lösungsansätze sind willkommen.
Danke schon mal im Voraus! Hoffe das ist alles einigermaßen schlüssig...
-
Kurz eine Frage: Warum sollte man eine Klasse in eine seperate Lib auslagern ? Mir ist kein Fall bekannt in dem so etwas sinnvoll ist. Mach doch eine Klasse Interface, welche die gemeinsamen Funktionen von B und C deklariert und bilde dann die Subklassen B und C.
class Interface { virtual void Hallo(); } class B: public Interface { void Hallo(); } class A: public Interface { void Hallo(); } int main(int argc, char** argv) { Interface* interface; if (Test()) interface = new A(); else interface = new B(); interface->Hallo(); }Ich würde dir generell das Broker Pattern (http://www.vico.org/pages/PatronsDisseny/Pattern%20Broker/) empfehlen da du ja anscheinend zwei Klassen Dienste anbieten und diese getrennt voneinander agieren. Könnt aber auch möglich sein dass ich damit Spatzen auf Kanonen schiesse.
-
Hi,
es geht bei mir darum, dass ich eine möglichst modulare Engine schreibe, was auch das Handling von Render- und/oder "Window"-APIs mit einschließt. Heißt soviel wie, ich kann je nach Konfiguration SDL oder Win32 - DirectX oder OpenGL auswählen. In jeder Library befindet sich praktisch eine API die dann später dynamisch dazugelinkt wird. Deswegen die verschiedenen Libs, für die modularität, bzw. Erweiterbarkeit.
Gruß,
PuerNoctis
-
Okay, ich hab das ganze jetzt erstmal anders geregelt. Ich habe die Klassen jetzt soweit gegenseitig bekannt gemacht, dass ich über Get-Methoden auf meine Flags zugreifen kann...
Falls jemand trotzdem noch Hinweise/Anmerkungen/Kritik/Ideen zu o.g. Struktur hat, einfach schreiben.
Gruß,
PuerNoctis
-
Verstehe ich das richtig ? Du willst eine Engine bauen, welche nur über eine Projektconfig DirectX, OpenGL, SDL oder Windows (GDI) unter einen Hut bringt ?
Das ist keine leichte Aufgabe, denn jede Bib hat so ihre Tücken und Macken. Und nicht jedes grafisches Objekt lässt sich leicht von der Windows GDI in DirectX transformieren.
-
Ist mir bewusst, und es ist mir klar, dass das ein harte Stück Arbeit ist
Aber ich hab' mir einfach mal gedacht, das probierste jetzt - kann nur davon lernen 
Ich versuche tatsächlich, und dem kann man gut und gerne mit einem Lachen begenen, diese ganzen APIs nach außen gleich hinzustellen, alle "unter einen Hut zu bringen". Bis jetzt muss ich sagen klappt das sogar prima, hätte ich nicht gedacht. Probleme gibt es aber trotzdem immer wieder, schon allein weil OGL eine State-getriebene API ist, DX nicht....
Mal gucken wie weit ich noch komme

EDIT: Rechtschreibfehler...
-
PuerNoctis schrieb:
Ist mir bewusst, und es ist mir klar, dass das ein harte Stück Arbeit ist
Aber ich hab' mir einfach mal gedacht, das probierste jetzt - kann nur davon lernen 
Ich versuche tatsächlich, und dem kann man gut und gerne mit einem Lachen begenen, diese ganzen APIs nach außen gleich hinzustellen, alle "unter einen Hut zu bringen". Bis jetzt muss ich sagen klappt das sogar prima, hätte ich nicht gedacht. Probleme gibt es aber trotzdem immer wieder, schon allein weil OGL eine State-getriebene API ist, DX nicht....
Mal gucken wie weit ich noch komme

EDIT: Rechtschreibfehler...
Da wünsche ich dir viel Glück!

Es kommt hald drauf an, inwiefern du spezielle Features benutzen willst. So grundsätzliche Sachen sind bestimmt relativ einfach, aber sobald es komplexere Dinge werden geht das mit einer anderen API vlt. gar nicht.
Aber viel lernen kannst du da bestimmt, auch wenn ich, wenn ich dich wäre nicht allzu grosse Hoffnungen machen würde, dass es am Schluss wirklich was "brauchbares" wird.
btw.
Kompliment für die schöne Beschreibung oben! Sieht man hier leider sehr selten, dass es eine so schön übersichtliche Beschreibung des Problemes gibt.
-
Danke für das Kompliment

Leider weiß ich nur zu gut, dass es die Hölle ist sich in fremdem und zum Großteil unkommentiertem Code reinzulesen, deswegen die Mühe. Obwohl's trotzdem noch nen Tick besser ginge ^^.Die Sache mit den speziellen Features wird wirklich noch eine große Hürde. Entweder ich implementiere irendwelche rechenintensiven Workarounds die gewisse Funktionalität in den anderen APIs wiederspiegelt, oder ich beschneide die jeweilige API eben um diese speziellen Dinge..... oder das Projekt wird mangels Machbarkeit eingestellt. Egal wie, schon allein das Ziel so etwas zu schaffen hilft bei der Steigerung der Kreativität, daher mache ich mir jetzt mal keine Gedanken darum ob's am Ende wirklich "was brauchbares" ist.

Aber das eigentliche Problem hat sich ja erstmal erledigt. Danke für die Comments.