Problem/Frage mit new/delete und dynamisch erzeugten Objekten
-
Hallo
Ich habe folgende Typen von Objekten:
class OClass { foo(); ... } class UClass1 : OClass { blub(); ... } class UClass2 : OClass { ... }Nun bekomme ich zur Laufzeit erst mitgeteilt, wieviele Objekte von UClass1 und UClass2 ich brauche.
Da ich auch oft wahlfrei auf diese zugreifen muss, wollte ich sie neu anlegen, in einem Vektor speichern, benutzen und am Ende des Programms wieder löschen. Vorstellen tu ich mir das etwa so (nur klappt das nich):vector v<OClass *>; int count1 = getAmountUClass1(); int count2 = getAmountUClass2(); // Objekte erstellen (funktioniert so) UClass1 * clas1; for (int i = 0; i < count1; i++) { clas1 = new UClass1(parameters); v.push_back(clas1); } ... // benutzen klappt v.at(0)->foo(); // benutzen (klappt nicht) v.at(0)->blub(); ... // löschen (lässt sich compilieren - aber obs funktioniert weiß ich nicht) for (int i = 0; i < v.size(); i++) { delete v.at(i); }Klappt so nicht bedeutet in diesem Fall, dass es sich bereits nicht kompilieren lässt.
Wer kann mir da mal auf die Sprünge helfen ? Vermute, das ich gar nicht so schwer nur ist "drauflosraten" auch unschön.
Vielen Dank & Viele Grüße,
Benjamin
-
Du kannst über ein bestimmtes Objekt nur auf die Methoden zugreifen, die es selber definiert (oder vererbt) - auch wenn es in Wahrheit eine ganz andere Klasse ist (d.h. selbst wenn du in Wahrheit ein "UClass1"-Objekt hast, kannst du nur die Methoden von "OClass" ansprechen.
Lösung wäre es, alle benötigten Methoden in der Basisklasse zu definieren und dann in jeder abgeleiteten Klasse zu überschreiben.
-
Hi!
Erstmal, was für Fehler kommen denn?
Und was mir beim überfliegen gleich auf fällt:
vector< OClass *> v;Edit: Genau, mach OClass Abstrakt und alle Methoden rein virtuell. Außerdem nich vergessen den Destruktor virtuell zu machen!

grüße
-
Der Fehler der bei
v.at(0)->blub();vom Compiler gemeldet wird, ist der, dass er die Funktion nicht findet.
Was soll mit demhier sein? :
vector< OClass *> v;@CStoll:
Das ist aber doof, weil die nur beiden Unterklassen jeweils ~10 verschiedene Funktionen haben (mit denen die andere nix anfangen könnte) und nur 4 gemeinsame.
edit:
Will sagen: Gibt es keine andere Lösungsmöglichkeit ?Danke schonmal soweit !
-
Hi!
vector< OClass *> v;Damist ist, das es bei dir im Qellcode total verdreht ist...
vector v<OClass *>;Das ist aber doof, weil die nur beiden Unterklassen jeweils ~10 verschiedene Funktionen haben (mit denen die andere nix anfangen könnte) und nur 4 gemeinsame
Du kommst halt nich drum rum. Evtl. ganz unschön mit rumgecaste, daran will ich aber garnich denken!

Du kannst ja die Methoden überschreiben, so das ein Fehler auftritt falls sie (fälschlicherweise) aufgerufen wird.
grüße
-
ok, ich machs erstmal so, dass ich die betroffenen funktionen die ich akut brauche in die basisklasse packe.
dann bleibt meine letzte frage noch offen:
// Objekte erstellen UClass1 * clas1; for (int i = 0; i < count1; i++) { clas1 = new UClass1(parameters); v.push_back(clas1); } // löschen (lässt sich compilieren - aber obs funktioniert weiß ich nicht) for (int i = 0; i < v.size(); i++) { delete v.at(i); }Funktioniert das Löschen ? Ich wüßte nicht, wie ich üerprüfen kann, ob meine mit "new" angelegten Objekte auch wirklich gelöscht werden. Wäre auf Dauer ziemlich übel wenn dem nicht so ist

-
Warum benutzt du nicht einfach zwei Vektoren? Einen für UClass1-Objekte, einen für die UClass2-Objekte. Dann würdest auch auch new und delete verzichten können.
-
Hallo
Ich wüßte nicht, wie ich üerprüfen kann, ob meine mit "new" angelegten Objekte auch wirklich gelöscht werden
Du kannst dir im Destruktor von UClass1 eine Ausgabe auf zum Beispiel std::cout machen. dann siehst du wann was gelöscht wird.
bis bald
akari
-
Zwei Vectoren benutzen ist in dem Fall kontraproduktiv, weil ich dann jeweils vorher entscheiden müsste, in welchem der Vektoren denn das gewünschte Objekt liegt. Eine Eigenschaft der Oberklasse netscheidet, welches Objekt konkret angesprochen werden soll.
Da müsste ich dann jedesmal durch zwei Vektoren durchgucken. Denke, da ist der Overhead nicht unbeträchtlich (das ganze passiert oft).Das mit dem cout im Destruktor habe ich probiert und es funktioniert. Danke. Eigentlich ja ganz einfach

-
Vorweg: Meine Erfahrung ist noch sehr begrenzt, aber wieso löst Du das Problem nicht mit dynamic_cast? Evtl. zu zeitintensiv, zuviel overhead?
Bin mir nicht sicher, was für Nachteile man evtl. alles mit einem dynamic_cast bekommt.Aber man könnte doch einfach:
... if (UClass1* v2 = dynamic_cast<UClass1*>(v.at(0))) { v2->blub(); } else if (UClass2* v2 = dynamic_cast<UClass2*>(v.at(0))) { ... } ...machen, oder?