Anfängerfrage zu OOP
-
Vielleicht hilft dir das:
include <iostream> #include <stack> using namespace std; class a{ public: int gib_wert(){ return 2; } }; int main() { std::stack<a> st; // STL-Stack als Datenstruktur im Programm a ar[3]; // Hier hast du 3 "a"s auf DEM Stack des laufenden Programms st.push(ar[0]); st.push(ar[1]); st.push(ar[2]); std::cout << st.top().gib_wert() << std::endl; cin.get(); }
Edit: CPP-Tags
-
#include <stack> ... std::stack<a> my_stack; a instanz; my_stack.push(instanz);
So? Oder wolltest du die Stack-Klasse selbst schreiben?
-
Hallo,
und wie kann ich so ne Instanz wieder los werden?
Ich wolte nen Ballerspiel machen mit ner Klasse Kugel.
Wenn Jemand feuert soll ne Instanz von Kugel erzeugt werden, im Stack gespeichert werden um bei jedem Bild gemalt werden. Anschließend wenn die Kugel eingeschalgen ist, soll die Instanz gelöscht werden.Ich glaub nen Stack ist nicht das Beste. Was würdet Ihr stattdessen nehmen?
-
Andreas XXL schrieb:
Ich glaub nen Stack ist nicht das Beste. Was würdet Ihr stattdessen nehmen?
Ne verkettete Liste (std::list). So hast du Zugriff auf alle Kugeln und Einfüge/Löschoperationen gehen recht schnell.
-
Hi!
Zum auslesen ist die Methode top() und zum löschen den obersten Elements ist es pop().
Problem ist, wenn eine andere Kugel vor der obersten einschlägt (was sehr wahrscheinlich ist) kannst du die nicht entfernen. Vielleicht wäre da ein vector geeignet.Code-Hacker
-
Hallo,
Danke, aber ich meine wie ich die Instanz selber löche.
Ist der Speicher wirklich wieder frei gegeben, wenn ich die Instanz nur aus dem Vector lösche?Ich hab da mal was über new und deleate und malloc gelesen, aber nicht richtig verstanden. Muss man nicht davon etwas benutzen?
-
Hi!
Nein. malloc in C++ sowieso nicht, wenn dann new und delete, aber da du kein new verwendet hast, brauchst du auch kein delete. new und delete brauchst du für dynamische Speicherreservierung, was man in C++ aber imho eher seltener braucht.
Edit:
Du musst auch nicht vor dem pushen eine Insatz anlegen du kannst das auch direkt machen:vector<a> bla; bla.push_back(a());
Code-Hacker
-
Hab mal ein kleines Beispiel zusammgehackt:
#include <list> #include <iostream> using namespace std; class Kugel { public: Kugel():id(++gid) { } ~Kugel() { cout << "Kugel " << id << " wird geloescht" << endl; } int getID() const { return id; } private: int id; static int gid; }; int Kugel::gid = 0; int main() { Kugel k1, k2, k3; std::list<Kugel> l; l.push_back(k1); l.push_back(k2); l.push_back(k3); for(std::list<Kugel>::iterator it = l.begin(); it!=l.end(); ++it) cout << "Kugel " << it->getID() << endl; std::list<Kugel>::iterator it = l.begin(); ++it; l.erase(it); // 2. Kugel löschen for(std::list<Kugel>::iterator it = l.begin(); it!=l.end(); ++it) cout << "Kugel " << it->getID() << endl; cin.get(); return 0; }
-
Hallo,
so ganz verstehe ich das nicht!
Also, ich musste den code etwas modifizieren, wegen Fehlern durch Neudefinition.
Jetzt sieht er so aus:
#include <list> #include <iostream> using namespace std; class Kugel { public: Kugel():id(++gid) { } ~Kugel() { cout << "Kugel " << id << " wird geloescht" << endl; } int getID() const { return id; } private: int id; static int gid; }; int Kugel::gid = 0; int main() { Kugel k1, k2, k3; std::list<Kugel> l; l.push_back(k1); l.push_back(k2); l.push_back(k3); for(std::list<Kugel>::iterator it = l.begin(); it!=l.end(); ++it) cout << "Kugel " << it->getID() << endl; it = l.begin(); ++it; l.erase(it); // 2. Kugel löschen for( it = l.begin(); it!=l.end(); ++it) cout << "Kugel " << it->getID() << endl; cin.get(); return 0; }
Als Ausgabe erhalte ich:
Kugel 1
Kugel 2
Kugel 3
Kugel 2 wird gelöscht
Kugel 1
Kugel 3
//jetzt muss ich was eingeben z.B
egalKugel 1 wird gelöscht
Kugel 3 wird gelöscht
Kugel 3 wird gelöscht
Kugel 2 wird gelöscht
Kugel 1 wird gelöschtDas kann ich mir nicht werklären!
-
Andreas XXL schrieb:
Kugel 1
Kugel 2
Kugel 3
Kugel 2 wird gelöscht
Kugel 1
Kugel 3
//jetzt muss ich was eingeben z.B
egalKugel 1 wird gelöscht
Kugel 3 wird gelöscht
Kugel 3 wird gelöscht
Kugel 2 wird gelöscht
Kugel 1 wird gelöschtDas kann ich mir nicht werklären!
Jo, das passt auch. Zur Ausgabe:
Kugel 1,2,3 werden in der 1. Schleife ausgegeben.
Dann wird Kugel2 gelöscht und deren Destruktor aufgerufen, weshalb in der
folgenden Schleife nur noch Kugel 1 und 3 ausgegeben werden
Nach deiner Eingabe endet main und der Gültigkeitsbereich für die Liste sowie alle Kugeln endet, weshalb sie zerstört werden (Da die Liste zuerst auf den Stack gepusht wurde, wie ihr Destruktor auch zuerst aufgerufen)
-
Hallo,
aber warum wird Kugel 2 nochmal gelöscht, ich dachte die wär schon wiklich vorher gelöscht worden?
-
Andreas XXL schrieb:
Hallo,
aber warum wird Kugel 2 nochmal gelöscht, ich dachte die wär schon wiklich vorher gelöscht worden?
Weil die Übergabe an push_back per value passiert, sprich: Die Variable wird kopiert und beim Löschen wird eben der Dtor der Kopie aufgerufen. Beim Verlassen von main wird dann das "Original" gelöscht.
-
Und wie würde ich vorher das original löschen?
Kannst du mir auch erklären, was new free und malloc machen und warum man das hier nicht braucht?
-
Andreas XXL schrieb:
Und wie würde ich vorher das original löschen?
Kannst du mir auch erklären, was new free und malloc machen und warum man das hier nicht braucht?
Ich glaube, du solltest erst noch ein paar Tutorials und Bücher durchlesen, denn call by value und call by ref sind die Basics. Ein Objekt, das sich auf dem Stack befindet kann man nicht so einfach löschen. Bei solchen Objekten wird implizit der Destruktor aufgerufen, wenn sie ihren lokalen Gültigkeitsbereich verlassen. Hier wär noch ein Beispiel mit Zeigern (hier kannst du die Lebensdauer eines Objekts selbst bestimmen):
#include <list> #include <iostream> using namespace std; class Kugel { public: Kugel():id(++gid) { } ~Kugel() { cout << "Kugel " << id << " wird geloescht" << endl; } int getID() const { return id; } private: int id; static int gid; }; int Kugel::gid = 0; int main() { // 4 Kugeln auf dem Heap anlegen Kugel* k = new Kugel; Kugel* k2 = new Kugel; Kugel* k3 = new Kugel; Kugel* k4 = new Kugel; std::list<Kugel*> l; l.push_back(k); // Jetzt speichern wir Zeiger in der List l.push_back(k2); // d.h, es wird der Zeiger kopiert und NICHT das ganze l.push_back(k3); // Objekt for(std::list<Kugel*>::iterator it = l.begin(); it!=l.end(); ++it) cout << "Kugel " << (*it)->getID() << endl; std::list<Kugel*>::iterator it = l.begin(); ++it; delete *it; // Kugel 2 vom Heap löschen l.erase(it); // Zeiger auf den nicht mehr gültigen Block entfernen for(std::list<Kugel*>::iterator it = l.begin(); it!=l.end(); ++it) cout << "Kugel " << (*it)->getID() << endl; // Kugel 4 löschen weil ich Bock drauf hab: delete k4; // Hier wird auch der Dtor aufgerufen cin.get(); return 0; }
-
Hallo,
ich habe das jetzt so verstanden:
Bitte sagt mal ob jetzt alles richtig verstanden habe.Kugel* k = new Kugel;
Mit new erzeugt man dynamisch neuen Speicher für die Instanz des Objektes und erhält einen Zeiger auf die Instanz.Mit delete k löscht man die Instanz und gibt den speicher wieder frei.
Vorher wird der destrukor aufgerufen!Packt man den Zeiger in einen Vector, wird dort natürlich nur der Zeiger auf den Speicherplatz gespeichert.
Mit delete kann man wieder die Instanz löschen. Es bleibt noch der zeiger im vector, der jetzt nur noch auf etwas zeigt, was nicht mehr da ist(weil mit delete gelöscht)
Also löscht man mit .erase() noch diesen ZeigerUnd alles ist gut!
-
Andreas XXL schrieb:
Hallo,
ich habe das jetzt so verstanden:
Bitte sagt mal ob jetzt alles richtig verstanden habe.Kugel* k = new Kugel;
Mit new erzeugt man dynamisch neuen Speicher für die Instanz des Objektes und erhält einen Zeiger auf die Instanz.Mit delete k löscht man die Instanz und gibt den speicher wieder frei.
Vorher wird der destrukor aufgerufen!Packt man den Zeiger in einen Vector, wird dort natürlich nur der Zeiger auf den Speicherplatz gespeichert.
Mit delete kann man wieder die Instanz löschen. Es bleibt noch der zeiger im vector, der jetzt nur noch auf etwas zeigt, was nicht mehr da ist(weil mit delete gelöscht)
Also löscht man mit .erase() noch diesen ZeigerUnd alles ist gut!
Absolut richtig
-
Hallo,
ich habe noch eine Frage:Ich habe meine Klasse so gebaut wie die Klasse Kugel.
Nun benutze ich in Kugel einen Stack um etwas zu berechnen.Komischerweise Klappt das bei der ersten Kugel gut. Aber bei der zweiten Kugel geht es nicht mehr!
Sind dann die Stacks in den verschiedenen instanzen von kugel getrennt, oder schreiben alle Instanzen in den selben Stack?
-
Andreas XXL schrieb:
Hallo,
ich habe noch eine Frage:Ich habe meine Klasse so gebaut wie die Klasse Kugel.
Nun benutze ich in Kugel einen Stack um etwas zu berechnen.Komischerweise Klappt das bei der ersten Kugel gut. Aber bei der zweiten Kugel geht es nicht mehr!
Sind dann die Stacks in den verschiedenen instanzen von kugel getrennt, oder schreiben alle Instanzen in den selben Stack?
Wenn sie nicht statisch sind, dann sind das individuelle Instanzen. Aber dein Design ist schlecht. Wieso sollte eine Kugel einen Stack haben? Eine Kugel hat einen Schaden, ne Geschwindigkeit, Masse etc, aber gewiss keinen Stack (mal abgesehen davon, dass Stack hier eine ungünstige Datenstruktur ist). Wenn du mehrere Kugeln verwalten willst, dann schreib lieber nen Manager (BulletManager).