Dynamisches Array und OOP ( es wird die Funktion des Parents aufgerufen)
-
Hi an Alle.
Ich habe da ein kleines Problem der Vererbung einer Methode.
Ich habe zwei Klassen:class TObject { public: virtual double calc_intersection(TRay ray) { return -1; } };und
class TKugel : public TObject { public: TVec3d position; double radius; double calc_intersection(TRay ray); };Also eigentlich eine Einfache Vererbung.
nun möchte ich ein Array aus verschiedenen TObjects bauen, in welches ich natürlich Kugeln, oder Ebenen oder andere von TObject abgeleitete Klassen hinein stecke. Mein Versuch dazu sah folgendermaßen aus:
void TRaytracer::addObj( TObject obj) { static int length = this->obj_arr_length; TObject* newobjarr; newobjarr = new TObject[length+1]; for ( int i = 0; i < length; i++) { newobjarr[i]= this->objArray[i]; } newobjarr[ length ] = obj; delete [] this->objArray; this->objArray = newobjarr; this-> obj_arr_length++; //std::cout << this->obj_arr_length; };rufe ich jetzt aber auf jedem Object in diesem Array die calc_intersection Methode auf, so wird immer die vom Parent, also TObject aufgerufen. Ich nehme an, es stimmt irgendetwas nicht mit dem Array. Da ich allerdings noch nicht allzu lange c++ programmiere, weiß ich nicht genau, was er hinter den Kulissen macht.
wäre für Lösungen und Erklärungen jeglicher Art dankbar.
-
Na logisch wir die Methode von
TObjectaufgerufen, da es sich umTObjects handelt...EDIT: Wieso überlässt du die Speicherverwaltung nicht einem
std::vector?
-
Da bin ich mir eben nicht sicher. Ich gebe ja einen Zeiger auf eine Kugel in die Funktion addObj.
TKugel kugel; kugel.position.setvec(0,0,5); kugel.radius =1; //.. ../// tracer.addObj(kugel);in der Methode wird das Array um eins verlängert und die Kugel an die letzte Stelle gepackt.
und den Vector Datentyp werde ich mir mal ansehen. Danke
-
Polymorphie funktioniert nur, wenn du Verweise (Zeiger oder Referenzen) auf die abgeleitete Klasse aufhebst - in deiner Methode AddObj kopierst du das übergebene Objekt*, dabei gehen alle Anteile von TKugel, TEbene etc verloren.
Du solltest die Objekte am besten in einem vector<TObjekt *> (oder ptrvector) unterbringen und dann immer nur den Zeiger auf das anfangs erzeugte Objekt verwenden.* genau genommen bekommst du sogar ein nacktes TObjekt in die Funktion, weil du clevererweise den Parameter per Wert entgegennimmst.
-
Mhm. ich hatte angenommen, dass wenn ich ein Object als Parameter in eine Function schmeiße, sowieso nur der Pointer auf das Objekt übergeben wird.
Naja. Aber vector scheint genau das zu sein, wonach ich suche. Dann erspare ich mir die Speicherverwaltung. Danke
-
Du bist nicht zufällig von Java oder C# nach C++ gekommen? Wenn ja, gewöhn dich besser daran, daß du hier nur dann Pointer bekommst, wenn du explizit danach verlangst.
-
CStoll schrieb:
Du bist nicht zufällig von Java oder C# nach C++ gekommen? Wenn ja, gewöhn dich besser daran, daß du hier nur dann Pointer bekommst, wenn du explizit danach verlangst.
Fast. Hab bisher immer Object-Pascal Programmiert. Will aber auf c++ umsteigen, da ich jetzt auf meinem Linux Rechner programmieren will.
Ich weiß, es gibt vorbehalte gegen die Borland Delphi IDE, aber eigentlich fand ich es gar nicht so schlecht von Delphi immer gleich ein Fenster zu bekommen.
-
Objekt Pascal ist nicht gleich Objekt Pascal. Ich bin mit dem alten Turbo Pascal mit OOP-Erweiterung groß geworden. Da musste man noch Zeiger explizit definieren und New/Dispose als Procedur-Aufrufe verwenden. In Delphi scheint das anders zu sein. Da ist eine Variable eines Klassen-Typs implizit nur ein Zeiger. Genauso sind in Sprachen wie Java und C# Variablen von Klassen-Typen nur Referenzen. In C++ gibt es diese aufgezwungene Indirektion nicht. Vorteil: Mehr Regularität und Objekte können auf dem Stack angelegt werden. Das ist so ziemlich das wichtigste, was Du erstmal verstehen solltest. Am besten besorgst Du Dir ein schlaues C++ Buch und parkst Dein Delphi-Wissen im Keller. Das dürfte eher hinderlich beim C++ Lernen sein.