Estoy creando un par de clases Vector2
(X e Y) y Vector3
(X, Y y Z), pero no sé si hacer Vector3
heredar Vector2
o si volver a implementar las variables miembro m_x
y m_y
otra vez. ¿Cuáles son los pros y los contras de cada lado (herencia vs redefinición)?
Editar: estoy usando C ++ (VS2010).
c++
architecture
Mark Ingram
fuente
fuente
Vector3
debería ser solo 3floats
en lo que respecta a la memoria. No digo que sea imposible, solo que nunca he visto eso en un motor de producción.floats
. Ya sabes, YAGNI, KISS, todas esas cosas.Vector2
,Vector3
yVector4
sin herencia yfloats
solo es realmente el estándar de facto en los motores de juego.typedef float real;
;).Respuestas:
No, no debería. Lo único que usaría de la herencia son los componentes
x
yy
. Los métodos utilizados en unaVector2
clase no serían útiles en unaVector3
clase, probablemente tomarían diferentes argumentos y realizarían operaciones en un número diferente de variables miembro.fuente
Vector3
IS-NOT-AVector2
(por lo que no debe heredar), pero unApple
IS-AFruit
(por lo que puede heredar). Si tuerce su mente lo suficiente, tiene unVector3
HAS-AVector2
, pero la pérdida de rendimiento y la codificación de dificultad significa que escribirá clases completamente separadas paraVector3
yVector2
.Hay algo curioso que puede hacer con C ++ (no especificó un idioma, y esta respuesta se debe principalmente a que creo que es bueno ver alternativas, aunque realmente no creo que esto sea útil en la mayoría de los casos).
Usando plantillas puedes hacer algo como esto:
y esto se puede usar así:
Como dije, no creo que esto sea útil, y probablemente complicará tu vida cuando trates de implementar puntos / normalizar / otras cosas y trates de ser genérico con cualquier número de vectores.
fuente
Vector3f v
un poco más bloatyVector3<float> v
typedef
distancia.Independientemente de la velocidad, la primera pregunta que debe hacerse al hacer una herencia es si los va a usar polimórficamente. Más específicamente, ¿hay alguna situación en la que puedas verte usando un
Vector3
como si fuera unVector2
(que, al heredar de él, estás diciendo explícitamente que un Vector3 "es-un" Vector2).Si no, entonces no deberías usar la herencia. No deberías estar usando la herencia para compartir código. Para eso están los componentes y las funciones externas, no es que compartirías ningún código entre ellos de todos modos.
Dicho esto, es posible que desee formas fáciles de convertir
Vector3
s aVector2
s, y en ese caso puede escribir una sobrecarga del operador que truncará implícitamenteVector3
a aVector2
. Pero no deberías heredar.fuente
Vector2
sino heredar de una baseVector<N>
? Eso tiene mucho sentido. Además, ¿por qué la herencia significa automáticamente un comportamiento polimórfico? Una de las mejores cosas de C ++ es que puede tener una herencia de costo cero. No es necesario agregar ningún método virtual (incluidos los destructores virtuales) en laVector<N>
clase base .No, dado que todos los métodos tendrán que ser anulados también, no tendrá que heredarlos.
Si algo, ambos podrían implementar una interfaz de Vector. Sin embargo, dado que probablemente no desee agregar / sub / dot / dst entre un Vector2 y un Vector3, esto tendrá efectos secundarios no deseados. Y tener diferentes parámetros, etc. sería una molestia.
Así que realmente no puedo ver ninguna ventaja de la herencia / interfaz en este caso.
Un ejemplo es el marco Libgdx, donde Vector2 y Vector3 no tienen nada que ver entre sí, aparte de tener el mismo tipo de métodos.
fuente
Si planea usar las matrices SIMD, es probable que sean las mejores. Si aún desea utilizar la sobrecarga del operador, puede considerar usar una interfaz / mixin para acceder a la matriz subyacente; por ejemplo, aquí hay un punto de partida que solo tiene el (no probado)
Add
.Observe que no he proporcionado
X
/Y
/Z
, cadaVectorX
clase heredaría directamente de esta, por las mismas razones especificadas por otras personas. Aún así, he visto matrices utilizadas como vectores muchas veces en la naturaleza.Descargo de responsabilidad: mi C ++ podría apestar, ha pasado un tiempo desde que lo usé.
fuente
_aligned_malloc
significa que el error que abrí no es realmente un error?__m128
registro, debe usar_mm_loadu_ps
en su lugar. Una buena clase de muestra está aquí en "vectorclass.zip"_mm_loadu_ps
debería funcionar para usted con esa estructura (donde_mm_load_ps
no lo hará). También agregué tu sugerencia: siéntete libre de editar la pregunta si crees que estoy ladrando el árbol equivocado (ha pasado un tiempo desde que usé C [++]).Otra desventaja seria de que Vec3 herede de Vec2 o, posiblemente, de que ambos hereden de una sola clase de Vector: su código hará muchode operaciones en vectores, a menudo en situaciones de tiempo crítico, y le conviene asegurarse de que todas esas operaciones sean tan rápidas como sea posible, mucho más de lo que es para muchos otros objetos que no son bastante universal o de bajo nivel. Si bien un buen compilador hará todo lo posible para aplanar cualquier sobrecarga de herencia, todavía confía más en el compilador allí de lo que le gustaría; en cambio, los construiría como estructuras con la menor sobrecarga posible y posiblemente incluso trataría de hacer que la mayoría de las funciones que las usan (con la excepción de cosas como operador + que realmente no se pueden evitar) sean globales en lugar de métodos en el estructura La optimización temprana generalmente se recomienda contra, y con una excelente razón,
fuente