Polymorphie-Probleme
-
Hallo zusammen,
ich habe eine Abstrakte Basisklasse:
class BaseCell { public: vector<BaseCell*> *v; BaseCell () : v(NULL) {} virtual void add ( BaseCell* )=0; };und zwei Abgeleitete Klassen, SpecialCellA und SpecialCellB, die im Wesentlichen gleich aussehen:
class SpecialCellA : public BaseCell { public: void add (BaseCell* ptr) { if (v==NULL) v = new vector<BaseCell*>; if ( BaseCell ist Zeiger auf SpecialCellA ) for (int i=0; i < ptr->v->length() ; i++) add( ptr->(*v)[i] ); else v->push_back(ptr); } };(SpecialCellB ebenso)
Ich möchte, dass die Methode SpecialCellA::add() SpecialCellA-Objekte elementweise und alle anderen als Zeiger hinzufügt (dabei dreht sich die Methode add() nicht im Kreis, weil alle Objekte auf der untersten Ebene aus Objekten der Klasse SpecialCellC bestehen werden, die sich nicht weiter zerlegen lässt).
Mein Programm müsste also entscheiden können, welchen Typ das Objekt hat, das hinter dem Basisklassenzeiger steht.Mir fällt dazu nur ein Typfeld oder etwas in der Art mit einer Fallunterscheidung ein, aber genau das soll die Polymorphie ja verhindern!
Am liebsten wären mir natürlich zwei seperate Methoden, eine für jeden Fall.Ich hoffe, jemand hat eine Idee, und bedanke mich fürs Lesen,
Morph
-
In deinem Fall dürfte ein dynamic_cast ausreichen:
if(dynamic_cast<SpecialCellA*>(ptr) != NULL) { kopiere CellA-Objekt } else { füge sonstiges Objekt ein }
-
Basisklasse:
class SpecialCellA; class SpecialCellB; class BaseCell { protected: virtual void addMeTo ( SpecialCellA * Cell ) = 0; virtual void addMeTo ( SpecialCellB * Cell ) = 0; public: vector<BaseCell*> *v; BaseCell () : v(NULL) {} virtual void add ( BaseCell* )=0; };Abgeleitete Klasse:
class SpecialCellA : public BaseCell { virtual void addMeTo ( SpecialCellA * Cell ) { if (v) for (int i=0; i < v->length() ; i++) Cell->add( (*v)[i] ); } virtual void addMeTo ( SpecialCellB * Cell ) { if (v) Cell->v->push_back(this); } public: void add (BaseCell* ptr) { if (v==NULL) v = new vector<BaseCell*>; Ptr->addMeTo (this); } };Alles ungetestet, Benutzung auf eigene Verantwortung.
-
Hallo Morph01,
was heißt bei dir elementweise hinzufügen. Sprich, was willst Du mit SpecialCellA anders machen, Du kannst die Objekte aller von BaseCell abgeleiteten Klassen deinem vector<BaseCell*> v hinzufügen. (Warum eigentlich *v ?)
Wenn Du die Klassen unerschiedlich behandeln willst, implemtier das auch in der entsprechenden Unterklasse. Also z.B.
class BaseCell{ public: .... virtual void add(BaseCell*){ ptr->addMe(this); }; virtual void addMe(BaseCell*)=0; virtual void elementAdd(BaseCell*)=0; virtual void zeigerAdd(BaseCell*)=0; } class SpecialCellA: public BaseCell { public: ... void elementAdd (BaseCell* ptr) { //ptr wird elemetweise hinzugefügt. } void zeigerAdd (BaseCell* ptr) { //ptr per Zeiger hinzugefügt. } void addMe (BaseCell* ptr) { // Ich bin vom Typ A und möchte elementweise hinzugefügt werden: ptr->elementAdd(*this) } }; class SpecialCellB{ public: .... void addMe (BaseCell* ptr) { // Ich bin vom Typ B und möchte per zeiger hinzugefügt werden: ptr->zeigerAdd(*this) } }Wahrscheinlich brauchst Du elementAdd und zeigerAdd gar nicht.
-
Hmm, hab mich wohl mit "SpecialCellB ebenso" etwas ungenau ausgedrückt: Ich möchte, dass SpecialCellB::add() Zeiger auf SpecialCellA-Objekte als Zeiger und SpecialCellB-Objekte Elementweise hinzufügt (also genau umgekehrt).
DJohn, dein Vorschlag tut das ja nicht, sondern fügt SpecialCellB-Objekte IMMER Als Zeiger hinzu, das will ich aber nicht.
Z2, ich hab deine Lösung ausprobiert, funktioniert gut, vielen Dank.
CStoll's Lösung mit dem dynamic_cast klingt auch viel versprechend, ich guck mal, welche ich nehme.Warum ich das ganze überhaupt machen will? Ich möchte eine Klasse schreiben, mit der man mathematische Terme darstellen kann. Dafür schreibe ich Klassen Summe, Produkt und Pbo (Primzahl-Basiertes Objekt, d.h. Potenzen,Wurzeln und das additiv Inverse einer Primzahl). Da nun aber z.B. ein Produkt sowohl weitere Produkte (die einfach aufgelöst werden können) als auch Summen (die mit dem Distributivgesetz aufgelöst werden können) enthält, kam ich auf die Idee mit der virtuellen Basisklasse.
Mein Ziel ist es, eine exakte Darstellung reeller Zahlen zu schaffen (sodass man z.b. 1+3*sqrt(2) als reelle Zahl speichern kann).Wünscht mir Glück!

Also, nochmal vielen Dank an alle, ich denke, dass mein Problem jetzt gelöst ist,
Morph