Ich erstelle ein paar Klassen Vector2
(X & Y) und Vector3
(X, Y & Z), aber ich weiß nicht , ob machen Vector3
von erben Vector2
, oder ob neu implementieren die Membervariablen m_x
und m_y
wieder? Was sind die Vor- und Nachteile jeder Seite (Vererbung vs. Neudefinition)?
Bearbeiten: Ich verwende C ++ (VS2010).
c++
architecture
Mark Ingram
quelle
quelle
Vector3
sollte a nur 3 seinfloats
, was den Speicher betrifft. Ich sage nicht, dass das unmöglich ist, nur, dass ich das noch nie in einem Serienmotor gesehen habe.floats
. Weißt du, YAGNI, KISS, all das Zeug.Vector2
,Vector3
undVector4
ohne Vererbung undfloats
nur ist wirklich der De-facto-Standard in Game-Engines.typedef float real;
;).Antworten:
Nein, sollte es nicht. Das einzige, was Sie aus der Vererbung verwenden würden, sind die Komponenten
x
undy
. Die in einerVector2
Klasse verwendeten Methoden wären in einer Klasse nicht nützlichVector3
. Sie würden wahrscheinlich unterschiedliche Argumente verwenden und Operationen mit einer unterschiedlichen Anzahl von Mitgliedsvariablen ausführen.quelle
Vector3
IS-NOT-AVector2
(also sollte es nicht erben), aber einApple
IS-AFruit
(also kann es erben). Wenn Sie Ihren Verstand genug verdrehen, ist einVector3
HAS-AVector2
drin, aber der Leistungsverlust und die Schwierigkeitsgradcodierung bedeuten, dass Sie fürVector3
und vollständig separate Klassen schreibenVector2
.Mit C ++ können Sie eine kuriose Sache machen (Sie haben keine Sprache angegeben, und diese Antwort ist hauptsächlich deshalb so, weil ich finde, dass es schön ist, Alternativen zu sehen, obwohl ich glaube, dass dies in den meisten Fällen nicht wirklich nützlich ist.)
Mit Vorlagen können Sie Folgendes tun:
und das kann so verwendet werden:
Wie gesagt, ich halte dies für nicht nützlich und es wird wahrscheinlich Ihr Leben verkomplizieren, wenn Sie versuchen, Punkte / Normalisierungen / andere Dinge zu implementieren und generisch mit einer beliebigen Anzahl von Vektoren zu arbeiten.
quelle
Vector3f v
ein bisschen aufblähenVector3<float> v
typedef
entfernt.Unabhängig von der Geschwindigkeit ist die erste Frage, die Sie sich stellen sollten, wenn Sie eine Vererbung durchführen, ob Sie sie polymorph verwenden werden. Genauer gesagt, gibt es eine Situation, in der Sie sich vorstellen können, wie Sie a verwenden,
Vector3
als wäre es einVector2
(was Sie explizit sagen, wenn Sie davon erben, dass ein Vektor3 ein Vektor2 ist).Wenn nicht, sollten Sie keine Vererbung verwenden. Sie sollten keine Vererbung verwenden, um Code freizugeben. Dafür sind Komponenten und externe Funktionen gedacht, nicht dass Sie irgendeinen Code zwischen ihnen teilen würden.
That being said, können Sie einfache Möglichkeiten wollen convert
Vector3
sVector2
s, und in diesem Fall können Sie einen Operator Überlastung schreiben, die implizit gestutzt werden ,Vector3
um einenVector2
. Aber du solltest nicht erben.quelle
Vector2
sondern von einer Basis zu erbenVector<N>
? Das macht durchaus Sinn. Warum bedeutet Vererbung außerdem automatisch polymorphes Verhalten? Eines der besten Dinge an C ++ ist, dass Sie keine Kosten für die Vererbung haben können. Keine Notwendigkeit, fügen Sie alle virtuellen Methoden (einschließlich virtuelle Destruktoren) in derVector<N>
Basisklasse.Nein, da auch jede Methode überschrieben werden muss, können Sie nicht wirklich davon erben.
Wenn überhaupt, könnten beide eine Vector-Schnittstelle implementieren. Da Sie jedoch wahrscheinlich nicht / sub / dot / dst zwischen einem Vector2 und einem Vector3 hinzufügen möchten, hat dies unerwünschte Nebenwirkungen. Und verschiedene Parameter usw. zu haben, wäre ein Ärger.
Daher kann ich in diesem Fall wirklich keine Vorteile der Vererbung / Schnittstelle erkennen.
Ein Beispiel ist das Libgdx-Framework, bei dem Vector2 und Vector3 nichts anderes miteinander zu tun haben als die gleichen Methoden.
quelle
Wenn Sie vorhaben, SIMD- Arrays zu verwenden, sind diese wahrscheinlich die besten. Wenn Sie die Operatorüberladung dennoch verwenden möchten, können Sie erwägen, ein Interface / Mixin zu verwenden, um auf das zugrunde liegende Array zuzugreifen. Hier ist beispielsweise ein Ausgangspunkt, der nur das (nicht getestete) enthält
Add
.Beachten Sie, wie ich habe nicht vorgesehen
X
/Y
/Z
jedeVectorX
Klasse erben würde direkt von diesem - aus den gleichen Gründen von anderen Menschen angegeben. Trotzdem habe ich Arrays gesehen, die oft in freier Wildbahn als Vektoren verwendet wurden.Haftungsausschluss: Mein C ++ könnte scheiße sein, es ist schon eine Weile her, seit ich es benutzt habe.
quelle
_aligned_malloc
dass der Fehler, den ich geöffnet habe, nicht wirklich ein Fehler ist?__m128
Register zu bekommen ,_mm_loadu_ps
sondern stattdessen verwenden. Eine gute Beispielklasse finden Sie hier unter "vectorclass.zip"_mm_loadu_ps
sollte für Sie mit dieser Struktur funktionieren (wo_mm_load_ps
nicht). Ich habe auch Ihren Vorschlag hinzugefügt - zögern Sie nicht, die Frage zu bearbeiten, wenn Sie das Gefühl haben, dass ich den falschen Baum belle (es ist eine Weile her, seit ich C [++] verwendet habe).Ein weiterer schwerwiegender Nachteil, wenn Vec3 von Vec2 erbt oder wenn beide von einer einzigen Vector-Klasse erben: Ihr Code wird viel bewirkenvon Operationen an Vektoren, oft in zeitkritischen Situationen, und es liegt sehr in Ihrem Interesse, sicherzustellen, dass all diese Operationen so schnell wie möglich sind - viel mehr als bei vielen anderen Objekten, die dies nicht tun ganz so universell oder niedrig. Während ein guter Compiler sein Bestes tut, um den Vererbungsaufwand zu reduzieren, verlassen Sie sich immer noch mehr auf den Compiler, als Sie möchten. Stattdessen würde ich sie als Strukturen mit so wenig Aufwand wie möglich erstellen und möglicherweise sogar versuchen, die meisten Funktionen, die sie verwenden (mit Ausnahme von Dingen wie operator +, denen nicht wirklich geholfen werden kann), als globale statt als Methoden zu definieren struct. Eine frühzeitige Optimierung wird generell gegen und aus gutem Grund empfohlen,
quelle