vector mit basisklassen in einen mit abgeleiteten klassen casten?
-
@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.
-
@SeppJ sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Citation needed.
Sorry, das UB war an der Stelle falsch. Es leakt halt, und könnte in Folge ein UB ergeben. Da war ich in Gedanken schon wieder weiter.
-
@manni66 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Auch "nach" einem vector kann aufgeräumt werden:
Nur dann wenn der Container nicht bereits Objekte verloren hat, und der Sinn und Zweck eines Containers ist es, dass man sich genau darum nicht mehr kümmern muss.
-
Ein Memoryleak ist kein UB und führt auch nicht zu UB.
-
@Bashar sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Ein Memoryleak ist kein UB und führt auch nicht zu UB.
Erstaunlicherweise doch. Ich habe es auch nicht geglaubt und daher nachgeschlagen:
C++-Standard über object-lifetime:
A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitlycalling the destructor for an object of a class type with a non-trivial destructor. For an object of a class typewith a non-trivial destructor, the program is not required to call the destructor explicitly before the storagewhich the object occupies is reused or released; however, if there is no explicit call to the destructor or if adelete-expression(8.5.2.5) is not used to release the storage, the destructor shall not be implicitly called andany program that depends on the side effects produced by the destructor has undefined behavior
Sinn macht die Passage für mich nicht. Warum ist das undefined, wenn die Seiteneffekte nicht passieren, aber sich das Programm darauf verlässt? Sie passieren dann halt nicht, und das Programm ist falsch, aber das sollte doch meines Erachtens nach definiert sein. Da sehe ich keinen Unterschied zu einem Programmierfehler. Aber da steht, dass es undefiniert sei, und dann ist es eben so.
-
@Bashar sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Ein Memoryleak ist kein UB und führt auch nicht zu UB.
Dir ist schon bewusst, dass z.B. unter Linux in low memory Situationen Prozesse einfach mal so abgeschossen werden?
By default, Linux follows an optimistic memory allocation strategy. This means that when malloc() returns non-NULL there is no guarantee that the memory really is available. In case it turns out that the system is out of memory, one or more processes will be killed by the OOM killer. For more information, see the description of /proc/sys/vm/overcommit_memory and /proc/sys/vm/oom_adj in proc(5), and the Linux kernel source file Documentation/vm/overcommit-accounting.
-
@john-0 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
@Bashar sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Ein Memoryleak ist kein UB und führt auch nicht zu UB.
Dir ist schon bewusst, dass z.B. unter Linux in low memory Situationen Prozesse einfach mal so abgeschossen werden?
By default, Linux follows an optimistic memory allocation strategy. This means that when malloc() returns non-NULL there is no guarantee that the memory really is available. In case it turns out that the system is out of memory, one or more processes will be killed by the OOM killer. For more information, see the description of /proc/sys/vm/overcommit_memory and /proc/sys/vm/oom_adj in proc(5), and the Linux kernel source file Documentation/vm/overcommit-accounting.
Das ist kein undefined behavior.
-
@john-0 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
@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.
Das hatte ich schon gelesen, aber wie soll man denn einen nicht-besitzenden Zeiger in den
vector<X*>
packen (das wäre, mit C++98 Mitteln, ja noch komplizierter)?Und zu
Nur dann wenn der Container nicht bereits Objekte verloren hat, ...
Wie soll der Container denn Objekte verlieren?
-
@john-0 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
@Bashar sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Ein Memoryleak ist kein UB und führt auch nicht zu UB.
Dir ist schon bewusst, dass z.B. unter Linux in low memory Situationen Prozesse einfach mal so abgeschossen werden?
Ja, das ist mir bewusst, und dein Ton gefällt mir nicht.