008
06.09.2004, 15:18 Uhr
virtual
Sexiest Bit alive (Operator)
|
Zitat von ~Dani: |
Und wieder mal haben wir ein Problem mit einem Vector.
Wir haben einen vector vom typ Medium, da stehen Objekte unterschiedlicher Unterklassen drin. ALso zB CdAudio, Tape, Vinyl.
[...]
Wenn wir jetzt aber
C++: |
mainVec[i].getType();
|
aufrufen, wird immer in die getType Methode von Medium verzweigt und nicht in die Richtige Unterklasse.
Woran liegt das??? Kann es sein dass im Gegensatz zum Array, in einem Vector die Datentypen verloren gehen???
|
Ja, aber nicht im Unterschied zu einem Array: wenn Du etwas in einen vektor reinschreibst, wird nicht etwa das Original reingetan, sondern eine Kopie. Die Kopie wird dabei durch den Aufruf vom Copy constructor von Medium gemacht, weil Du eben einen std::vector<Medium> hast. Die Informationen, die zusätzlich in einem CTape oder was auch immer stehen, gehen unweigerlich verloren.
Das hat auch einen Grund: Nimm einfach mal der einfachheit halber an, daß ein Vecotr intern ein Array ist. (Dem ist idR tatsächlich so). Ein Array zeichnet sich dadurch aus, daß alle Elemente den gleichen Typen haben. Also Medium. Erst diese Gleichheit macht es überhaupt möglich, daß man schnell auf die Elemente zugreifen kann. Denn in der Regel werden Spezielisierungen von Medium Felder an die Medium Klasse hinzufügen und damit ein Objekt größer machen. Wären die Felder nicht gleich groß, müsste zB beim Zugriff auf das 100ste Feld zunächst zusammengerechnet werden, wie groß die Felder 1 - 99 sind, um überhaupt herauszufinden, wo das 100ste Objekt anfängt.
Einen Ausweg gibt es auch: man tut in den Vektor nur noch Pointer:
C++: |
std::vector<Medium*> mainVec; ... mainVec.push_back(new CTape(...)); mainVec.push_back(new CVideo(...)); ... mainVec[0]->getType(); .
|
Problematisch ist hier, daß man nun selbst die Elemente freigeben muß, mit delete, weil man ja mit new gearbeitet hat. Aber auch dies kann man durch die Verwendung von Smart Pointern vermeiden:
C++: |
std::vector< smart_ptr<Medium> > mainVec; ... mainVec.push_back(new CTape(...)); mainVec.push_back(new CVideo(...)); ... mainVec[0]->getType(); .
|
-- Gruß, virtual Quote of the Month Ich eß' nur was ein Gesicht hat (Creme 21) Dieser Post wurde am 06.09.2004 um 15:20 Uhr von virtual editiert. |