Projektaufbau + Zugriff auf übergeordnete Klassen
-
in meinen Projekte fällt mir immer öfter auf, dass ich ständig auf Variablen
zugreife, die in der übergeordneten Klasse verwendet werden, weil ich diese
überall brauche. Möchte allerdings nicht gleich deshalb alles global machen.folgender Grobaufbau
Main.h
#ifndef MAIN_H #define MAIN_H #include "GameOptionen.h" #include "GameMenu.h" class Main { private: ... public: Main(); ~Main(); HWND hwnd; HINSTANCE hinst; .... GameOptionen oOptionen; GameMenu oMenu; bool exit(void); .... static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); }; // bekanntgabe der Instanz, welche in cpp erstellt wird, // da in assoziierten Klassen benoetigt extern Main *g_oMain; #endifMain.cpp
#include "Main.h" Main *g_oMain = NULL; // Alle Funktionen deklarierenDie Instanz von Main wird bei mir in der Einsprungmarke des Programmes erstellt.
In den Instanzen von GameOptionen und GameMenu benötige ich oftmals Fensterhandle usw. und greife mit g_oMain->hwnd drauf zu. Funktionieren tut das alles.
Nun zur Stylefrage:
Ist das so üblich oder sollte man alles, was man in so einer Klasse braucht, über Konstruktoren übergeben oder komplett global zur Verfügung stellen.
In dem Fall oben werden diese Objekte eh nur in dem Programm verwendet, weil sie sehr speziell sind. Vielleicht auch einfach eine Instanz von Main in den Unterklassen referenzieren. Würde mich wirklich interessieren, was empfohlen wird, weil die Größe der Projekte bei mir stetig zunimmt und ich am Ende nicht alles umschreiben will
Ich finde es persönlich schon wichtig, das Main() alle Daten meines Programms kapselt.
-
hmm.. ich bin mir nicht sicher, ob ich das richtig verstehe, aber wie willst du Main denn später verwenden?
Ich denke ja, dass man so etwas gar nicht erst braucht und ein Handle nicht viel mit dem Programm sondern mit der GUI zu tun hat etc.
Wenns dennoch sein muss:
Ich würde ja für so etwas plädieren:struct Main { /*...*/ void do_crap() {} void bar() {} /*..getter..*/ }; void foo1(Main& program) { program.do_crap(); } struct foo2 { foo2(Main& program) : program(program) {} void bar1() { program.bar(); } void bar2() { program.bar(); } private: foo2& operator= (const foo2&); foo2 (const foo2&); Main& program; }; int main() { Main program; foo2 x(program); x.bar1(); x.bar2(); foo(program); }das ganze kann man auch als pointer übergeben. manche mögen nicht-const referenzen nicht so sehr...
grundsätzlich halte ich es jedoch für falsch, in C++ ein programm als objekt zu sehen - obwohl es da mit sicherheit auch ausnahmen gibt.
wenn es gar nicht anders geht, kannst du dir mal das singleton-entwurfsmuster angucken. ist aber bestenfalls ein (hässlicher) workaround für globale variablen...
für was ist denn die main-klasse alles verantwortlich?
und in welchen teilen brauchst du denn eine instanz davon? und wozu und wo werden die teile erstellt etc...bb
-
Als ich bsp mit Winapi angefangen habe, wurden alle Funktionen in die Main.cpp geklatscht. Das wurde mir zuviel und ich hab versucht, dass objektorientierter zu machen.
Die Einsprungmarke des Programms:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hprevinst, LPSTR lpcmdline, int ncmdshow) { // Instanz von Klasse Main erstellen // Fensterhandle und Instanz an Klasse Main uebergeben // Fenster erstellen // Nachrichtenschleife // Instanz von Klasse Main freigeben }Alles andere ist bei mir dann in der Main. Ne statische WndProc und alles,
was mit dem Fenster zu tun hat.unskilled schrieb:
in welchen teilen brauchst du denn eine instanz davon?
Ja, du hast recht. Main ist eigentlich ne Singelton-Klasse. Darf also nur einmal instanziiert werden. Daraus resultiert natürlich logischerweisse die Frage, fuer was die Main-Klasse. Aber du glaubst ja garnet, wie übersichtlich alles auf einmal ist
.Zu der Idee mit der Referenz dentiere ich im Moment auch *grübel*