Vorteil von Klassen ...
-
Hi,
ich bin eigentlich ein VBler, und möchte nun auf C++ unmsteigen. Ich habe auch scho n ein paar Anwendungen geschrieben, mit denen man beispielsweise primzahlen errechnen kann und noch n paar mehr.
Allerdings erfährt man in dem Tutorial nich wirklich, was der nutzen von Klassen ist. Man erfährt nur, dass es helfen soll die Realität nachzubauen..., allerdings nicht wie man es in einem Programm einbauen kann.
Bezieht eure Antworten am besten auf dem Beispiel eines kleinen Strategiespiels, in welchem Klassen zum Beispiel die Einheiten sein sollen. Klassen definieren uns so ist kein Problem, lediglich bei der Vererbung und Konstruktoren.... hörts auf.
Also die Sachen, die es in VB sowieso nicht gibt
Gruß
Linux.Newbie
-
-
gutes buch kaufen & lesen!
-
Anfangs beschränken sich die Vorteile mal auf:
- Komplexität "kapseln"
- Beziehungen darstellen
Komplexität "kapseln"
Als "User" einer Klasse (also der Programmierer, der deine Klassen nutzt; anfangs bist das meist ohenhin
du selbst) braucht man, bzw. will man sogar nichts über einen internen Aufbau wissen. Bei deiner Klasse Einheit
wären zum Beispiel Positionen der Gliedmaßen, bzw die Datei aus der die Mesh dazu geladen wurde, etc.. alles
Eigenschaften, die für einen "User" nicht interessant sind. Du willst eigentlich nur auf eine bestimmte Position
feuern oder die Einheit bewegen lassen, etc .. Für den "User" wird also die Benutzung sehr viel leichter und
er kann sich auf das Wesentliche konzentrieren.Ein Codebeispiel dazu:
// Benutzung von C-Arrays void f() { // code, den wir benötigen, damit es überhaupt funktioniert .. int** array = new int*[10]; for(int j = 0; j < 10; ++j) { array[j] = new int[20]; } // mit 0 initialisieren for(int j = 0; j < 10; ++j) { for(int k = 0; k < 20; ++k) { array[j][k] = 0; } } // was wir eigentlich tun wollten .. int g = array[11][11]; // Fehler den niemand bemerkt, sofern er // nicht den Debugger benutzt .. // code, den wir benötigen, damit es überhaupt funktioniert .. for(int j = 0; j < 20; ++j) { delete[] array[j]; } delete[] array; } // und jetzt mit Klassen void g() { IntArray2Dim array(10, 20); int g = array[11][11]; // der Fehler kann hier erkannt werden, und // dementsprechend behandelt werden .. }
Mögen mir bitte all jene verzeihen, die eventuell einen Fehler in der Funktion f finden, bzw finden,
dass der Weg auch noch unnötig kompliziert dargestellt wurden.Andererseits, hat das natürlich auch noch Vorteile für dich (als Programmierer der Klasse). Zum Beispiel kannst du
die interne Darstellung ändern. Anfangs lädst du zum Beispiel das Aussehen der Einheit aus einer lokalen Datei, da
du aber übers Internet spielen können willst, und andere möglicherweise das Standardaussehen der Einheiten erweitert
haben, möchtest du plötzlich, dass das vor jedem Spiel angepasst wird. Somit lädst du das Aussehen aus einen
Netzwerk-Stream und nicht mehr aus einer Datei. Kein Problem, wenn du alles
brav gekapselt hast. Die Klasse könnte also dann so aussehen:class Unit { private: // ifstream appearance; NetworkStream appearance; // ... public: Unit(string appearanceId) { // appearance.open(appearanceId); appearance = NetworkConnection.loadAppearance(appearanceId); // ... } };
Nach außen hin ändert sich wunderbarerweise gar nichts, sprich der "User" deiner Klasse muss sich nicht auch noch
irgendwie auf die Änderungen einstellen, sondern bemerkt eben nichts von der internen Änderung.Für die restlichen Punkte kann ich mir jetzt leider keine Zeit nehmen.
Andererseits hab ich ach gerade den FAQ-Eintrag zu dem Thema gefunden:
Vorteile von Klassen --> wo denn??Ansonsten würde ich eben auch ein Buch empfehlen, bzw. einfach Praxis mit gleichzeitigem Vergleich zu dem
prozeduralen Weg. Hab gehört dass OOP für Dummies ganz gut sein soll.Gebe absolut keine Garantie auf Vollständigkeit, bzw. auf Korrektheit.
-
hi,
ich glaube ich kaufe mir doch ein buch
Welches würdet ohr mir da empfehlen?? Ich dachte schon an folgendes:Gruß
Linux.Newbie
-
schau vielleicht mal bei http://www.buecherbillig.de/category/Programmierung_C+plus+plus.html
da sind die bücher z.T. stark reduziert und du kannst dir 2 oder mehr bücher für den preis von einem, nicht restposten o.Ä., buch kaufen. über die qualität der bücher kann ich nichts sagen, aber ich hab mir da mal assemblerbücher gekauft und die warn net schlecht.MamboKurt
-
Wenn du normale Funktionen zum Kapseln benutzt, hast du einige Probleme vor dir:
- Das Datenmodell wird mit den zugehörigen Funktionen gewartet, jedoch muss man in irgendeiner Form den Zugriff auf ein bestimmtes Objekt Kapseln:int iMode[10]; // Access slots // Definition von daten für irgendwas void ModeInit() { int i; for (i=0; i< 10; i++) iMode[i] = 0; } int ModeOpen() { int i=0; for (i=0; i<10; i++) { if (iMode[i] == 0) return i; } return -1; } void MachWas(int slot) { // Mach was } void ModeClose(int slot) { // selbiges zum schliessen } // Zunächst initen ModeInit(); // Access id holen int iSlot; iSlot = ModeOpen(); MachWas(iSlot); if (iSlot == -1) printf("Nichts frei\n"); ...
Das Datenmodell ist zwar definiert, die Zugehörigkeit des Funktionsinterfaces ist aber nur per Dokumentation bzw. per Prafixe und Codeconventions ersichtlich. Ausserdem neigt man dazu, Fehler beim ID-Handling zu begehen, die man zwar per eingener Structs noch minimieren kann, allerdings bleibt das Problem der Zuordnung von Datenmodell und IF. Dazu muss die Datenstruktur per Init zunächst initialisret werden, was man nat. auch gern vergessen kann.
Klassen kapseln in sich das Datenmodell und das Interface, um dieses zu modifizieren:
class Mode { private: // Def datenmodell public: Mode() { // Init datenmodell } ~Mode() { // Term datenmodell } void MachWas() { } } // Zugriff: Mode MyMode; // <- Der Konstruktor hat bereits das Datenmodell initialisert MyMode.MachWas();
Das Intialisieren erfolgt durch das Erstellen einer Instanz, die Zugehörigkeit ist durch den Namen der Instanz und dem Interface eindeutiger, in der Klasse selbst können weitere komplexe Datenmodelle ebenfalls in Klassen vorhanden sein etc.
Aber das ist nur ein ganz kleiner Teil der Vorteile von Klassen, Weiterbildung ist zwingend erforderlich.
MfG Kimmi
-
nur mal sonne Frage am Rande:
was bringt jetzt eigentlich der Konstruktor, und vorallem der Dekonstruktor?Also wenn ich das richtig verstanden habe, dann dient der dazu, dass wenn man z.B. bei der Initialisierung einen Wert festlegen will, dies aber dann nicht bei jeder Initialisierung machen möchte, dass man sich einen Konstruktor schreibt, der dann aufgerufen wird, und dass für einen eledigt.
Ist es so?
-
Der Konstruktor wird ausgeführt, wenn eine Instanz erstellt wird, der Destruktor, wenn die Instanz gelöscht wird. Der Konstruktor wird in aller Regel zur Initialisierung des Objektes benutzt, also Startwerte zuweisen, Ressourcen anfordern, solche Dinge. Der Destruktor enthält traditionellerweise Code, der das wieder aufräumt, also zum Beispiel die angeforderten Ressourcen wieder freigibt.
Das hier dürfte es verdeutlichen:
#include <iostream> #include <string> class A { public: A(std::string const &name) : name_(name) { std::cout << "A::A() " << name_ << std::endl; } ~A() { std::cout << "A::~A() " << name_ << std::endl; } private: std::string name_; }; int main() { A a("foo"); { A a2("bar"); } A *p = new A("baz"); delete p; }
-
ok, thx