Vererbung, Composite - Kein Casting?
-
Hallo,
ich hab folgendes Problem:
Für ein kleines Programm, das in Archiven rumwühlt, habe ich eine virtuelle Dateistruktur erstellt, die aus dem Header geladen und im Fenster dargestellt wird. Dazu verwende ich das Composite-Muster, d.h. es gibt eine Basisklasse fsNode und davon abgeleitete Klassen fsDirectory und fsFile. Jedes Element (Verzeichnis und Datei) im Archiv wird nun einer der beiden Klassen zugeordnet. Nun gebe ich dem fsDirectory einen Vector<fsNode>, in dem die Inhalte gespeichert werden sollen, unabhängig davon, ob es Datei oder Directory ist.fsDirectory dummy; for (int i = 0; i < contents.size(); i++){ if (contents.at(i).getName() == name){ dummy = contents.at(i); return dummy; } }Wenn ich jetzt in Zeile 4 ein Element aus vector<fsNode> in den Dummy kopieren will, dann meckert der Compiler (VS2005) "there is no acceptable" conversion. Wie schaff ich es nun, dieses fsNode-Objekt - von dem ich weiß, dass es eigentlich ein fsDirectory ist - in ein fs Directory zu casten?
gruß Martin
P.S.: Bin eigentlich Java-Programmierer und beschäftige mich nun mit C++. Gibt es für o.g. Problem ggf. elegantere Lösungen unter C++? Probiere vieles so aus, wie ich es von Java gewohnt bin...
-
*reinterpret_cast<fsDirectory*>(&fsNode-Objekt);
-
error C2440: 'reinterpret_cast' : cannot convert from 'fsNode' to 'fsDirectory'
Conversion requires a constructor or user-defined-conversion operator, which can't be used by const_cast or reinterpret_castSagt der VS2005-Compiler dazu.

-
1. vector<fsnode> ist schlecht. Wenn du polymorphe Objekte by-value kopierst -- wie hier, wenn du sie z.B. in den Vektor einfügst -- wird tatsächlich nur das Basisklassenobjekt eingefügt. Das heißt, ein fsFile-Objekt wird auf seinen fsNode-Anteil zurechtgestutzt ("slicing"). Daher: polymorphe Objekte immer per Zeiger oder Referenz herumreichen.
2. reinterpret_cast ist hier nicht angebracht. Du kannst entweder dynamic_cast anwenden, wenn du nicht sicher bist, dass der Cast sicher ist. Du bekommst dann einen Nullpointer bzw. eine Exception, wenn der Cast nicht durchgeführt werden kann, weil das dahinterliegende Objekt doch nicht das ist was du erwartet hattest. Wenn du dir aus irgendwelchen Gründen ganz sicher bist, dass der Cast klappt, kannst du auch static_cast benutzen.
-
Aha, das klingt gut. Ein Verhalten, dass ich nicht erwartet hätte, mit dem ich aber leben kann.
Würde dann einfach einen vector<fsNode*> machen, in dem ich die Zeiger sammele. Und dann neue Objekte mit
fsDirectory *dummy = new fsDirectory(...); contents.push_back(dummy);einfügen?
-
Genau. delete nicht vergessen.
-
Ok, das würd ich dann spontan so machen (um den ganzen Vector aufzuräumen):
fsDirectory::~fsDirectory(){ fsNode* dummy; for(size_t i = 0; i < contents.size(); i++){ dummy = contents.at(i); delete dummy; } contents.clear(); }Bin mir aber nicht sicher, was der vector davon hält, wenn ich ihm die Pointer unter der Nase wegdelete. Zerstöre ich eigentlich den Pointer mit delete oder nur den Speicherbereich, auf den der Pointer weist?
-
fsDirectory::~fsDirectory(){ for(size_t i = 0; i < contents.size(); i++) delete contents[i]; }so reichts auch.
mad_martin schrieb:
Bin mir aber nicht sicher, was der vector davon hält, wenn ich ihm die Pointer unter der Nase wegdelete.
Das ist ihm egal. Er verwaltet die Pointer, nicht dass, worauf du damit zeigen willst.
Zerstöre ich eigentlich den Pointer mit delete oder nur den Speicherbereich, auf den der Pointer weist?
Nur das Objekt, auf das der Zeiger zeigt.
-
Danke sehr!