Jonathan hat geschrieben: ↑21.09.2020, 20:47
Alternativ könntest du natürlich
vector<Tier*> übergeben.
Falls das Problem noch nicht klar geworden ist: Im Vector liegen alle Objekte im Speicher hintereinander. Eine Ente ist aber unter Umständen größer als ein Tier, deshalb kann man ein
vector<Ente> nicht als
vector<Tier> interpretieren. Ggf. einfach mal das Memory-Layout aufmalen, dann sieht man es direkt.
Zeiger sind aber immer gleich groß, durch diese Indirektion tritt das Problem dann nicht mehr auf.
Danke für die Ausführung, das war mir tatsächlich nicht klar! Ist aber absolut schlüssig.
joeydee hat geschrieben: ↑22.09.2020, 12:48
Wenn ich richtig verstanden habe ... das prinzipielle Problem ist ja, alles irgendwie mit einer Stammklasse gemeinsam verarbeiten zu können, aber auf der anderen Seite auch mit bestimmten Komponenten (möglichst jederzeit und überall) wieder spezialisieren können, und das möglichst ohne Overhead. Sowas wie "Für alle Tiere: wenn du eine Ente bist ..." ohne ein Verbot auf Enten an dieser Stelle zu bekommen, und ohne dass man alle Eventualitäten für alle Tiere bereithalten müsste, was bei 3 Enten unter 1000 Tieren ja Quatsch wäre.
Hier z.B. klingt das auch ganz ähnlich:
viewtopic.php?f=4&t=4390
Vielleicht lohnt es ja, mal Data-Driven statt Object-Oriented als alternative Designlösung anzuschauen. In dem Fall auch unter "ECS", Entity-Component-System, zu finden. Bringt natürlich neue Probleme mit sich. Ist aber inzwischen mein Favorit bei dieser Art von Problemen.
Der wesentliche Unterschied zu OO ist:
OO bündelt
alle Eigenschaften für
ein Objekt in einem gemeinsamen "Container" (Klasse).
DD bündelt jeweils
eine Eigenschaft für
alle Objekte in einem gemeinsamen Container (Key-Value-Map).
Methoden in Objekten gib es dann auch nicht, Funktionalität für bestimmte Strukturen wird über Schleifen bzw. Filter und Ergebnislisten geregelt.
Jetzt verstehe ich die Idee! Wirklich raffiniert! Vielen Dank!
Wieso nimmst du dafür eine map? Verliert man nicht sehr viel Zeit, wenn man erst nach einem Element mittels Schlüssel suchen muss, ehe man darauf zugreifen kann? Wäre ein direkter Zugriff über einen std::vector nicht wesentlich schneller (das schnellste?)?
Alexander Kornrumpf hat geschrieben: ↑22.09.2020, 08:56
Oder von vornherein keine Vererbung verwenden. Oder ...
Ist sehr schwer eine beste Lösung vorzuschlagen wenn alles was wir über das Problem wissen ein Spielzeugausschnitt ist, der nicht kompiliert.
Danke deswegen an Jonathan, der das Problem nochmal geschärft hat.
Das stimmt schon, diese Situation ist nur eine Analogie. In meinem Code gehts tatsächlich um etwas anderes. Ich wollte fürs bessere Verständnis Irrelevantes ausklammern.
Aber vielleicht sind diese Informationen doch relevant.
Es geht halt darum, dass ich in meiner Kollisionsabfrage das behandelnde Elemente auf die restlichen prüfen muss und dieses eine Element auch interne Werte der anderen Elemente beeinflussen kann (z.B die velocity).
Ich habe also ein ausgewähltes Objekt A , mit welchem ich Berechnungen zu jedem Element einer Gruppe machen muss { B, C, D, E}.
Diese Gruppe ist nur ein Auszug einer noch grösseren Gruppe. Es sind die Elemente die mir mein Broad-Phase Algorithmus zurückgeliefert hat (Vorselektion).
Nun muss A zu jedem Element der Gruppe bestimmte Dinge berechnen, wie z.B. die Distanz. Einmal ausgerechnet, muss ich aber für diesen Zyklus darauf zugreifen können (heisst, solange bis Element B als Kandidat an der Reihe ist).
Nun ist es aber so, das B - wie A selbst - vielleicht ein Kreis ist. Hingegen C eine Wand-Line. Bei der Wand-Linie gibt es zwar auch eine Distanz, welche berechnet werden muss, im Vergleich zu einem Kreis, gibt es dann aber noch weitere Werte zu berechnen.
Ich wollte nicht, dass all diese Hilfsvariablen wie z.B. die Distanz ein fester Bestandteil der Klasse sind. Das würde die Klasse stark aufblähen und ich müsste sie nach gebrauch wieder manuell resetten. Das scheint mir einfach kein gutes Design zu sein.
Ich hab mir daher überlegt, den entsprechenden Klassen einfach einen Zeiger zu geben, der quasi auf ein temporäres "Datasheet" zeigt. Auf diesem sind alle Hilfsergebnisse gespeichert - und das ganze Sheet wird gelöscht, nachdem Objekt A behandelt wurde.
Bildlich gesprochen: Objekt A tackert Element B, C, D, E ein Zettel an die Stirn und schreibt darauf die relevanten Rechenergebnisse, wie z.B. die Distanz. Wenn A fertig ist, werden die Zettel wieder entfernt.
Auf was anderes komm ich irgendwie nicht :-X
Gruss starcow