Grundlegende Frage zu Instanzen - Laufzeiterzeugung
lima-city → Forum → Programmiersprachen → C/C++ und D
array
benutzer
buchen
code
dynamische erzeugung
frage
funktion
hund
instanz
katze
kreisen
laufen
laufzeit
pfiff
pointer
programm
radius
tier
vektor
zugriff
-
Hallo liebe Mitbewohner von Lima-City,
Ich habe zwei Fragen zur Erstellung und Handhabung von Instanzen zur Laufzeit in C++:
1.) Angenommen ich habe eine Klasse definiert, die einen Kreis darstellt. Zur Laufzeit (!) des Programms soll nun der Benutzer z.B. per Mausklick beliebig viele Instanzen erzeugen können. Wie mache ich das? Ich kann ja keine Namen im voraus vergeben. Wie greife ich dann auf die Instanzen zu? Meine einzige Idee war ein 1D-Array dieser Klasse zu nehmen und dann über den Index auf die Instanzen zuzugreifen. Aber geht das wirklich nur so?
2.) Schon etwas komplizierter: Angenommen ich habe eine Klasse "Tier" definiert, die die Elementfunktion "Laufen" besitzt. Von dieser Klasse "Tier" erben nun z.B. zwei Klassen "Hund" und "Katze" diese Elementfunktion.
An einer bestimmten Stelle des Programms (um anschaulich zu bleiben, in der Funktion "Pfiff" ) soll nun bei allen Instanzen von Hund und Katze die Methode "Laufen" ausgeführt werden.
Da die Instanzen von Hund und Katze aber zur Laufzeit erstellt werden, kann ich Laufen() aber nicht einfach in Pfiff() aufrufen... Außerdem kann ich bei zwei verschiedenen Typen (Hund und Katze) auch nicht mit einem Array arbeiten...
Ich hoffe ich konnte verständlich machen, wo bei mir die Frage liegt. Es ist immer schwer zu fragen, wenn man eigentlich nicht richtig weiß, wonach man sucht... -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Also: Bei 1. müssten Pointer dein Problem lösen. DIe Pointer selbst musst du beispielsweise in einem Array speichern (Nachteil an einem array: es hat eine maximale Größe, sind mehr erforderlich, wirds wieder komplizierter, Alternative: std::vector). Wenn du ein neues Obekt haben willst, suchst du dir einen freien Platz in deinem Array (oder std::vector) und erstellst das Objekt per
pointerArray[iUnusedPointerId] = new Object();
Zugriff dann per
pointerArray[i]->doSomething();
Genauers zu den Pointern musst du aber in einem tutorial oder buch nachlesen, das dauert hier zu lange und es gibt bereits gute Tutorias...
zu 2.: Da Stichwort hier heißt Polymorphie, bzw. virtuelle Funktionen. In deinem Beispiel muss "Laufen" eine virtuelle Funktion sein:
class Tier { public: virtual void laufen(){ ... }; public: void pfiff() {laufen();}; }; class Hund : public Tier { public: virtual void laufen(){ ... }; }
im folgenden sollte dann die "laufen"-Funktion des Hundes aufgerufen werden:
Hund _dog; _dog.pfiff();
imo sollte das so funktionieren...für eine Ausführliche Erklärung gilt auch hier wieder: Zu Ausführlich, das musst du dir in einem Buch oder Tutorial anlesen. Einfach mal nach virutelle Funktionen c++ suchen...
mfg, nomis
Beitrag zuletzt geändert: 14.1.2011 16:01:05 von nomis -
Hallo roboterbastler,
nomis hat ja schon vieles gut erklärt, also liefer ich halt noch ein paar Beispiele.
Für Punkt 1) empfehle ich dringend std::vector zu verwenden, da man im Voraus ja nie sagen kann, wie viele Kreise der Benutzer den haben will. Und wenn ich der Benutzer wäre, dann würde ich das Programm wegschmeissen, wenn es mir nach 50 Kreisen sagt, dass ich keine mehr hinzufügen darf.
Der Zugriff erfolgt im allgemeinen über den Index oder einen Iterator (danach kannst Du ja dann mal googlen).
Man kann allerdings auch eine von std::vector abgeleitete Klasse schreiben in der man beispielsweise Methoden wie findCircleByCenter() oder änliches nach belieben hinzufügen kann.
Eine kurze Dokumentation zu Vektoren findest Du z.B. hier.
Und hier hast Du eine kleine Beispiel wie man damit umgeht:
#include <iostream> #include <vector> using namespace std; class Circle { private: float center_x; float center_y; float radius; public: Circle(float x, float y, float r): center_x(x),center_y(y),radius(r) {} float getCenterX() const {return center_x;} float getCenterY() const {return center_y;} float getRadius() const {return radius;} void setCenterX(float x) {center_x = x;} void setCenterY(float y) {center_y = y;} bool setRadius(float r) { if(r<0) return false; radius = r; return true; } friend ostream& operator <<(ostream &os,const Circle *c); }; ostream& operator <<(ostream &os,const Circle *c) { os << "[" << c->center_x << "; " << c->center_y << ", " << c->radius << "]"; return os; } int main() { vector<Circle*> vcirc; /* dynamische Erzeugung von Kreisen */ for(int i=0; i< 10; i++) vcirc.push_back(new Circle(i, i, i)); /* Zugriff auf die Kreise */ for(unsigned long i=0; i < vcirc.size(); i++) cout << vcirc[i] << endl; /* löschen eines einzelnen Kreises: */ delete vcirc[3]; // Instanz zerstören vcirc.erase(vcirc.begin()+3); // Vektorelement löschen /* Aufräumen: alle Kreise löschen */ for(unsigned long i=0; i<vcirc.size(); i++) delete vcirc[i]; // Instanzen zerstören vcirc.clear(); // Vektor zurücksetzen return 0; }
Zum Thema 2) hat nomis ja bereits gesagt, wie man es macht, wenn man von vorneherein weiss, dass es eine Funktion pfiff() geben soll. Nämlich indem man sie in der Klasse Tier als Methode implementiert.
Es gibt aber noch eine zweite Möglichkeit, da ja sowohl Katze als auch Hund Tiere sind, kann man die Funktion pfiff() so schreiben, dass sie auf einem Vektor von Tieren operiert. Und ein Vektor der Tiere aufnimmt kann ja auch Katzen und Hunde aufnehmen.
Und hier das Anwendungsbeispiel:
#include <iostream> #include <vector> using namespace std; class Tier { private: bool tier_laeuft; public: Tier():tier_laeuft(false){} void Laufen() { tier_laeuft = true; } void Stopp() { tier_laeuft = false; } bool IstLaufend() const {return tier_laeuft;} }; class Katze: public Tier { public: Katze() {} }; class Hund: public Tier { public: Hund() {} }; void pfiff(const vector<Tier*> &tiere) { for(unsigned long i = 0; i<tiere.size(); i++) tiere[i]->Laufen(); } int main() { vector<Tier*> tiere; /* dynamische Erzeugung von 3 Katzen und 3 Hunden */ for(int i=0; i< 3; i++) tiere.push_back(new Katze()); for(int i=0; i< 3; i++) tiere.push_back(new Hund()); for(unsigned long i=0; i<tiere.size(); i++) cout << tiere[i]->IstLaufend() << endl; /* lasse die Tiere laufen: */ pfiff(tiere); for(unsigned long i=0; i<tiere.size(); i++) cout << tiere[i]->IstLaufend() << endl; /* Aufräumen: alle Tiere löschen */ for(unsigned long i=0; i<tiere.size(); i++) delete tiere[i]; // Instanzen zerstören tiere.clear(); // Vektor zurücksetzen return 0; }
Beitrag zuletzt geändert: 14.1.2011 22:27:33 von darkpandemic -
ich muss sagen, dass deine "Lauflösung" in diesem Fall wahrscheinlich passender ist, darkpandemic, da war ich etwas zu voreilig...
-
Danke für zwei so wunderbare, ausführliche Antworten!!! Ich habe das Problem damit lösen können!
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage