vector mit basisklassen in einen mit abgeleiteten klassen casten?
-
Übrigens hat der C++ Standard eine Grundbasis für einen Garbage Collector.
https://en.cppreference.com/w/cpp/memory/gc/pointer_safetyEin Leak UB machen und dann ein leak detector erlauben passt nicht zusammen.
-
@5cript sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
EDIT:
Im Standard unter "4.1.1 Abstract machine" wird erklärt wie der Standard das beobachtbare Verhalten eines Programmes "garantiert", und dass so lange sich die Implementierung equivalent zu dem beobachtbaren Verhält, das diese Implementierung erlaubt ist / Standardkonform ist. (as-if rule)
Undefined Behaviour bedeutet, dass die Garantie des Programmverhaltens vollständig entfällt. (bla bla festplatte formatieren bla)Was Undefined Behaviour ist, ist im Standard nicht "undefined" sondern kommt sehr sehr oft vor "XYZ is undefined behaviour if".
Also "nicht definiert" != "C++ UB"Der entscheidende Punkt ist, dass durch das Memory Overcommitment Eigenschaften des OS in Low Memory Situationen getriggert werden, die die Garantien der C++ ISO Norm konterkarieren. Die Norm garantiert Dir, dass eine Speicheranforderung entweder mit nullptr oder bad_alloc beantwortet wird, wenn der Speicher ausgeht, und man daraufhin das Programm zumindest wohl definiert beenden kann oder das Problem in einer anderen definierten Art und Weise lösen kannst. Genau das tritt dann aber nicht ein, sondern irgend ein Programm (es muss noch nicht einmal das Programm sein, dass die Low Memory Situation verschuldet hat) wird aus dem Speicher gekickt. D.h. das Laufzeitverhalten eines C++ Programm ist unter diesen Bedingungen eben nicht mehr definiert. Es ist UB nicht im streng formalistischen Sinne der Norm, sondern im dem Sinne, dass es Dir die Garantien der Norm unter den Füßen wegreißt.
Muss man deshalb so ein Fass in einem Anfänger Thread aufmachen? Ein kurzer Hinweis zur Klarstellung hätte ausgereicht. Anscheinend sind hier Nebensächlichkeiten wichtiger als der Umstand, dass man Anfänger klarmachen sollte, dass sie keine besitzenden Zeiger in Container ablegen sollten. Meiner Meinung eine vollkommen falsche Gewichtung der Thematik.
@5cript sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Ein Leak UB machen und dann ein leak detector erlauben passt nicht zusammen.
In der ISO Norm passt so einiges nicht zusammen. Ich hatte es an anderer Stelle schon angeführt, man darf zwar Allokatoren mit
propagate_on_container_swap == std::false_type
definieren, aber wenn man so einen Allokatoren mit einem Container verwendet und ein Swap stattfindet ist das UB. Das steht auch so in der Norm. Für C++17 noch verklausuliert, ab C++20 wohl direkt.
-
@john-0 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Muss man deshalb so ein Fass in einem Anfänger Thread aufmachen?
Selbstgespräch?
Du hast doch deinen anfänglich guten Hinweis aus dem Ruder laufen lassen.
-
@john-0 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Muss man deshalb so ein Fass in einem Anfänger Thread aufmachen? [...] Anscheinend sind hier Nebensächlichkeiten wichtiger als [...]
Das ist doch Tradition hier - Aber wenn eine Aussage seltsam oder falsch ist, dann führt das natürlich dazu dass das diskutiert wird. Ich würde nichts anderes erwarten.
(Vorausgesetzt das grundlegende Problem wurde ausreichend diskutiert und aufgelöst)
-
@Jockelx sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Mal abgesehen davon, dass die Klassenhierachie sehr fragwürdig ist, hast du einen shared_ptr genommen und keinen unique_ptr wie geschrieben.
Warum?
Und statt new nimm doch make_unique (bzw. shared) und deine for-schleife kopiert die ganze Zeit, was sie wohl nicht soll (darum?).@Jockelx:
Ich habe std::shared_ptr aus einer Mischung von Unwissenheit und Explorationsdrang genommen.Heißt ich habe einen Verwendungszweck für das Problem des TE gesehen und dachte mir dass das ein gutes Testprojekt für den Einsatz von C++11 Mitteln (std::unique_ptr und Co) sein könnte, da ich diese selten nutze.
Also habe ich ein Testprojekt aufgesetzt, damit ein wenig rumgespielt und verschiedene Szenarien getestet. Beispielsweise habe ich die Liste kopiert, danach verändert, die Liste danach Out Of Scope gehen lassen und die ursprüngliche Liste angesehen. Habe daher so Punkte wie
std::unique_ptr
oderfor (const auto&
vergessen, aber auch neue Dinge durch eurer Hinweise und Nachgooglen gelernt.Danke euch allen.
-
@john-0 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Grundsätzlich sind alle Container der C++ Standard Library nicht dafür geeignet, dass man darin besitzende POD Zeiger auf Objekte ablegt
Das ist natürlich völliger Quark. Man muss dann natürlich selber auf das Löschen dieser Zeiger achten, aber sonst ist da nix wildes bei. In C++98 ging es oftmals gar nicht anders.
-
@Tyrdal Wir leben nicht mehr in den 90ern. Kopier' mal so einen Vector ...
-
@Tyrdal sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Das ist natürlich völliger Quark. Man muss dann natürlich selber auf das Löschen dieser Zeiger achten, aber sonst ist da nix wildes bei. In C++98 ging es oftmals gar nicht anders.
Mit C++98 gab es bereits boost::shared_ptr (seit 1.23.0 dabei d.h. 2001), die man problemlos in Container ablegen konnte. auto_ptr war ja defekt und somit nicht wirklich benutzbar. Normale Zeiger legte man deshalb besser nicht in Containerklassen ab, weil RAII damit nun einmal nicht funktioniert und das seit C++98 eigentlich der Standard war. Wenn man das damals brauchte musste man sich halt eine eigene Wrapperklasse um den Zeiger herum bauen, weil es außer boost::shared_ptr nicht wirklich etwas Vorgefertigtes gab und unique_ptr war auf Grund der fehlenden move Unterstützung technisch nicht möglich.
Und bitte daran denken, wir reden hier über einen Anfänger, d.h. jemanden der nicht wirklich weiß wie man mit rohen Zeiger umgehen muss. Sein Code räumt die Zeiger jedenfalls nicht sauber ab.
-
@john-0 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Und bitte daran denken, wir reden hier über einen Anfänger, d.h. jemanden der nicht wirklich weiß wie man mit rohen Zeiger umgehen muss.
CppCon 2017: Bjarne Stroustrup “Learning and Teaching Modern C++” (7:15) Transkript: "...instead of stifling yet another innocent novice"
-
@Swordfish sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
@Tyrdal Wir leben nicht mehr in den 90ern. Kopier' mal so einen Vector ...
Manche tun das compiler technisch leider schon noch. Und so einen vector zu kopieren ist ja nun kein Problem. Die Ownership im Auge zu behalten ist das Problem. Und ja das geht mit smart pointern natürlich einfacher. Dazu wurden sie ja erfunden.
-
@john-0 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
@Tyrdal sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Das ist natürlich völliger Quark. Man muss dann natürlich selber auf das Löschen dieser Zeiger achten, aber sonst ist da nix wildes bei. In C++98 ging es oftmals gar nicht anders.
Mit C++98 gab es bereits boost::shared_ptr (seit 1.23.0 dabei d.h. 2001), d
C++ gibt's nun aber schon länger als seit 2001. Und ich persönlich kenne auch die Zeit vor 98. Ich sage nicht, daß das heutzutage die beste Idee ist, aber das das nun automatisch zum Ende der Welt führt ist nunmal auch nicht so.
-
@Tyrdal sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
C++ gibt's nun aber schon länger als seit 2001. Und ich persönlich kenne auch die Zeit vor 98. Ich sage nicht, daß das heutzutage die beste Idee ist, aber das das nun automatisch zum Ende der Welt führt ist nunmal auch nicht so.
In der Zeit vor der ISO Norm gab es aber keine STL, insofern erübrigt sich diese Diskussion dann ohnehin. Die STL entstand nach der Vorlage der Booch Components (noch für Ada entwickelt), und hat ganz klar die Intention, dass in den Container abgelegte Objekte vom Container verwaltet werden. Daher halte ich es nicht für zielführend hier einen Container in dieser Art und Weise zu nutzen. Dann doch lieber ein normales Array, da weiß man sofort, dass man selbst für die Datenhaltung verantwortlich ist.
@titan99_ sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
CppCon 2017: Bjarne Stroustrup “Learning and Teaching Modern C++” (7:15) Transkript: "...instead of stifling yet another innocent novice"
Ich halte das bei Container generell für schlecht, weil es gegen die Intention des Designs der Container geht. Bei Anfängern ist es nochmals schlechter.
-
@john-0 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Und bitte daran denken, wir reden hier über einen Anfänger, d.h. jemanden der nicht wirklich weiß wie man mit rohen Zeiger umgehen muss. Sein Code räumt die Zeiger jedenfalls nicht sauber ab.
Wäre es dann nicht sinnvoll den Thread zu splitten?
Ich fürchte wir haben den TE mit den ganzen Argumenten bereits erschlagen. Und wenn ich ehrlich bin mich auch.
-
@Tyrdal sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Die Ownership im Auge zu behalten ist das Problem.
Ähm ja. Warum denkst Du dass ich das sagte?
-
@john-0 sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Die STL entstand nach der Vorlage der Booch Components
Nein
-
@Quiche-Lorraine sagte in vector mit basisklassen in einen mit abgeleiteten klassen casten?:
Wäre es dann nicht sinnvoll den Thread zu splitten?
Definitiv!