vector mit basisklassen in einen mit abgeleiteten klassen casten?
-
struct D{}; struct E : public D { public: void doEStuff(){} }; std::vector<D*>*vecD = new std::vector<D*>; vecD->push_back(new E); vecD->push_back(new E); // kann ich irgendwie folgendes machen? std::vector<E*> *vecE = static_cast<std::vector<E*> *>(vecD); // damit ich danach das hier machen kann? for (auto e : vecE) e->doEStuff(); // ich weiß, dass es funktioniert wenn ich jedes einzelne element caste, kommt mir aber unnötig kompliziert vor
-
Wenn du weißt, dass nur E Elemente im vector sind, warum nimmst du dann nicht gleich einen vector<E*>?
-
@mael15 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Ohje, nein das kann man so nicht machen. Wenn überhaupt dann geht das nur mit einem dynamic_cast. Aber der Rest des Codes passt überhaupt nicht (Lies Dir bitte nochmals durch wie man einen std::vector richtig nutzt), und Du kannst nicht davon ausgehen, dass alle Elemente des vectors von Typ E sind.
-
@mael15 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
new std::vector<D*>
Warum Warum Warum Warum Warum!?!?
-
Dies ist ein sehr stark vereinfachtes Beispiel um die Frage zu klären, ob es technisch möglich ist. Es ist klar, dass das in diesem Beispiel keinen Sinn macht.
Die Antwort scheint "nein" zu sein.
-
@mael15 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Die Antwort scheint "nein" zu sein.
- Die Antwort ist, Dein Code ist schlecht – richtig schlecht. Deshalb auch der Hinweis darauf sich noch einmal das Thema
std::vector
durchzulesen. Man nutzt keinen Zeiger auf vector, weil das so keinerlei Sinn ergibt. - Man übergibt niemals einen besitzende POD Zeiger an einen
vector
, das knallt garantiert. - Dazu muss man wissen, dass man einen Downcoast nur mit
dynamic_cast
durchführen darf, d.h.static_cast
hat in diesem Kontext rein gar nichts zu suchen. - Die Basisklasse einer Klassenhierachie muss einen virtuellen Destruktor haben.
- Die Antwort ist, Dein Code ist schlecht – richtig schlecht. Deshalb auch der Hinweis darauf sich noch einmal das Thema
-
Vor einiger Zeit hatte ich eine ähnliche Frage, dort seht noch mehr zum Thema:
std::vector mit unterschiedliche grossen Datentypen.
-
@titan99_ sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Vor einiger Zeit hatte ich eine ähnliche Frage, dort seht noch mehr zum Thema:
Das Problem hierbei ist, dass der OP selbst sich die Mühe machen muss damit er was dabei lernt. Es ist kein Kunststück ihm funktionierenden modernen Code zu posten. Er müsste halt mal anfangen Verständnisfragen zu stellen – nur da kommt nichts.
-
@titan99_ danke dass du auf meine frage eingehst.
-
@mael15 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
// kann ich irgendwie folgendes machen? std::vector<E*> *vecE = static_cast<std::vector<E*> *>(vecD);
Nein.
-
vector<D*>
undvector<E*>
sind völlig unterschiedliche Klassen, der gemeinsame Nenner vector täuscht hier. Selbst wennD
undE
Gemeinsamkeiten besitzen oderE
vonD
erbt heisst das nicht, dassvector<D*>
undvector<E*>
diese Gemeinsamkeit übernehmen. Du kannst diese Gemeinsamkeiten/Vererbung nur auf Elementebene ausnutzen, aber nicht für den ganzen Container.
-
@DocShoe sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
vector<D*>
undvector<E*>
sind völlig unterschiedliche Klassen, der gemeinsame Nenner vector täuscht hier. Selbst wennD
undE
Gemeinsamkeiten besitzen oderE
vonD
erbt heisst das nicht, dassvector<D*>
undvector<E*>
diese Gemeinsamkeit übernehmen. Du kannst diese Gemeinsamkeiten/Vererbung nur auf Elementebene ausnutzen, aber nicht für den ganzen Container.Das ist nicht korrekt, da hier POD Zeiger auf Klassen abgelegt werden. Grundsätzlich sind alle Container der C++ Standard Library nicht dafür geeignet, dass man darin besitzende POD Zeiger auf Objekte ablegt, weil das zu UB führt. Wenn man besitzende Zeiger in Container ablegen will, muss man Smart Pointer nutzen d.h. shared_ptr oder unique_ptr.
-
Dann sind, deiner Meinung nach, alle bestehenden C++98-Programme mit
vector<X*>
UB?
-
@john-0 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Das ist nicht korrekt, da hier POD Zeiger auf Klassen abgelegt werden. Grundsätzlich sind alle Container der C++ Standard Library nicht dafür geeignet, dass man darin besitzende POD Zeiger auf Objekte ablegt, weil das zu UB führt. Wenn man besitzende Zeiger in Container ablegen will, muss man Smart Pointer nutzen d.h. shared_ptr oder unique_ptr.
soso
-
@DocShoe sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
soso
Was ist
D*
bzw.E*
für ein Typ?
-
@Th69 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Dann sind, deiner Meinung nach, alle bestehenden C++98-Programme mit
vector<X*>
UB?Wie wäre es mit korrektem Lesen? Das steht das Wort besitzenden und das sollte man nicht überlesen.
-
@john-0 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
weil das zu UB führt
Warum?
vector<X*> v; v.push_back( new X );
ist dann UB,
X* aX; aX = new X;
aber nicht?
-
@manni66 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Warum?
vector<X*> v; v.push_back( new X );
ist dann UB,
X* aX; aX = new X;
aber nicht?
Beides zusammen leakt
ist UB, da kein delete ausgeführt wird.Wenn man korrekt rohe Zeiger nutzt,
int main () { int* p = new int; // do something with p delete p; }
hier gibt es kein Leak mehr
ist das kein UB, sofern "something" da nicht querschiesst.Aber bei
#include <vector> int main () { std::vector<int*> vec; vec.push_back(new int); // wird hier die Ownership an den Container übertragen } // <- und hier wird der Stack aufgeräumt und dann gibt es ein memory leak.
Bei der main function wird der Müll vom OS aufgeräumt, aber bei jeder anderen Funktion würdest Du hier bei jedem Aufruf ein
int
verlieren – nicht gut.
-
@john-0 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Beides zusammen ist UB, da kein delete ausgeführt wird.
Citation needed.
-
@john-0 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Beides zusammen ist UB, da kein delete ausgeführt wird.
Ist ein memory leak UB?
Auch "nach" einem vector kann aufgeräumt werden:
int main () { std::vector<int*> vec; vec.push_back(new int); // do something with vec for_each( begin(vec), end(vec), [](auto p) { delete p; } ); }
Aber es ist natürlich völlig richtig, dass besitzende Zeiger besser keine rohen Zeiger sind, ob in einem Container oder nicht.