Vererbung und static_cast Problematik
-
BorisDieKlinge schrieb:
...da aber die Liste immer objekte in abwechsender reihenfolge enhält würd ich eben static_cast nutzen.. aber nur wegen der performance!
du "optimierst" an der falschen stelle.
-
Wenn man zwei unterschiedliche Objekttypen in einen Container steckt und beim
spätern Zugriff in JEDEM FalL wieder casten muss, dann ist dies, meines
Erachtens, (oft) schlechtes Design. Denn offentsichtlich haben die "Items" in
dem Container keine Gemeinsamkeit und stecken offenbar nur aus Bequemlichkeit
in einem gemeinsamen Container.
Aufgrund deiner lückenhaften Beschreibung kann ich natürlich nicht sagen ob
dein konkretes Problem eine Ausnahme darstellt.
-
@redhead: schau dir mal mein ersten post an.. hätten sie keien gemeinsamkeit würd ich das natürlich nich tun.. die haben gleiceh basisattribute, aber unterscheiden sich eben in extra parametern!
@publicServiceAnnouncement: Erklär mal...
-
BorisDieKlinge schrieb:
naja dynamic_cast ist sicher wenn ich jedesmal überprüfe ob es wirklich Typ A oder B ist,
das macht dynamic_cast mit dem idiom, das ich vorhin gepostet habe, von selber.
BorisDieKlinge schrieb:
da aber die Liste immer objekte in abwechsender reihenfolge enhält würd ich eben static_cast nutzen.. aber nur wegen der performance!
selbst wenn du weißt, was da drin ist, solltest du ein dynamic_cast benutzen. so schrecklich langsam (es sind ein paar if-abfragen...) ist es nicht und wird dich vor bösen überraschungen bewahren, wenn doch mal was mit den daten nicht passt.
wenn du weißt, was drin ist, dann stellt sich mir die frage: warum nutzt du nicht void* und reinterpret_cast, das ist noch schneller... publicServiceAnnouncement hat schon recht, du optimierst an der falschen stelle.
-
Aber redhead hat recht. Wenn du bei jedem Objekt genau sagen kannst, welchen typ es hat(weil sie immer abwechselnd kommen), dann spricht das schon sehr deutlich dafür, dass du eher 2 listen brauchst.
Hinzu kommt, dass dir bisher in jedem thread zum Thema casten gesagt wurde, dass casten grundsätzlich auf ein schlechtes Design hinausläuft, also würde ich an deiner Stelle mal überprüfen, ob die leute nicht mit ihrer Vermutung recht haben.
@ghost wenn man es genau weis, dann ist static_cast die richtige wahl. Es sind halt eben nicht immer nur ein paar ifs.
Und bei void* mit reinterpret_cast ist implementationsabhängig, was da rauskommt.Mal davon ab, dass man den letzten rest typsicherheit wegwirft.
Und nur mal btw: static_cast kostet dich ganz genau 0 Takte. zumindest solange du keine virtuelle vererbung nutzt.
-
Du solltest dir nicht beim Design überlegen, ob eine einzelne Operation zuviel Zeit braucht. Wenn das Programm fertig ist und dann nicht schnell genug ist, nimmst du einen Profiler und schaust, wo die Zeit verbraucht wird. Meistens kann man dann durch nen schlaueren Algorithmus viel mehr rausholen, als durch das einsparen von ein paar Casts.
-
BorisDieKlinge schrieb:
@redhead: schau dir mal mein ersten post an.. hätten sie keien gemeinsamkeit würd ich das natürlich nich tun.. die haben gleiceh basisattribute, aber unterscheiden sich eben in extra parametern!
Da du in deinem Beispiel jedesmal castest scheint die gemeinsame Basisklasse in
DEINEM Beipiel ja eben KEINE Rolle zu spielen. Bei Verwendung von virtuellen
Funktionen und Überschreiben könntest du dir dann nämlich das casten sparen.

-
otze schrieb:
@ghorst wenn man es genau weis, dann ist static_cast die richtige wahl. Es sind halt eben nicht immer nur ein paar ifs.
was man ungefähr nie mit absoluter sicherheit sagen kann, wenn man nicht vorher mit anderen methoden geklärt hat, was das für ein objekt tatsächlich ist oder eben mit absoluter sicherheit weiß, was da passiert.
otze schrieb:
Und bei void* mit reinterpret_cast ist implementationsabhängig, was da rauskommt.Mal davon ab, dass man den letzten rest typsicherheit wegwirft.
ironie-detektor einschalten.
-
ghorst schrieb:
oder eben mit absoluter sicherheit weiß, was da passiert.
Was i.A. der Fall ist wenn man immer ein A und ein B in Folge in den Container packt

Ich bin auch der Meinung, wenn sicher ist, welches Objekt es ist, kann man static_cast nutzen. Wenn's dann kracht, ist es ein Programmierfehler wie ein Segfault oder Division durch Null.
Andere Sache Boris:
Wenn IMMER ein A* und ein B* hintereinander in dem Container liegen, warum nutzt Du dann keinen Container von pair<A*,B*>? Dann kannst Du Dir die Casterei ganz sparen, und die Bedingung "zu einem A gehört ein B" wäre durch die Semantik schon leichter zu erfüllen. Vererbung kannst Du ja dennoch nutzen, um die Gemeinsamkeiten abzubilden, dabei muss die Vererbung nichtmal virtuell sein.
-
LordJaxom schrieb:
Wenn's dann kracht, ist es ein Programmierfehler wie ein Segfault oder Division durch Null.
aus meiner sicht ist aber vor allem einer, den man nicht suchen möchte.

-
wie hoch ist die wahrscheinlichkeit das diese fehler auftritt wenn ich die liste so fülle:
for(int i=1; i< x; i++){ if(i%2) LISTE.Add(new A); else LISTE.Add(new B); }???
-
ich glaub, so was nennt man dann designfehler.

bau dir, wie lordjaxom es vorschlug, ein struct, pair oder ähnliches und mach päarchen draus, dann sparst du dir das lästigen casten und erhältst einen sauberen code.
-
das mit dem pair ist ja wunderschön... aber es muss nicht sein das es immer diese reihenfolge ist... es kann auch ein anderes muster sein...das ist das problem...
-
wenn es regelmäßig ist und die periode nicht zu lang, kannst du immernoch eine struct benutzen oder eben für jede klasse eine eigene liste aufziehen. (der verwaltungsaufwand dafür ist auch nicht zu groß.)
ansonsten hilft dir doch nur ein dynamic_cast.
-
otze schrieb:
Und nur mal btw: static_cast kostet dich ganz genau 0 Takte. zumindest solange du keine virtuelle vererbung nutzt.
Also immer. Denn mit static_cast sind Downcasts aus einer virtuellen Basisklasse heraus sowieso nicht möglich.