Estou criando um par de classes Vector2
(X & Y) e Vector3
(X, Y & Z), mas eu não sei se para fazer Vector3
herdar a partir de Vector2
, ou se a re implementar-as variáveis de membro m_x
e m_y
de novo? Quais são os prós e os contras de cada lado (herança versus redefinição).
Edit: Estou usando C ++ (VS2010).
c++
architecture
Mark Ingram
fonte
fonte
Vector3
deve ser apenas 3 nofloats
que diz respeito à memória. Não estou dizendo que é impossível, só que eu nunca vi isso em um mecanismo de produção.floats
. Você sabe, YAGNI, KISS, todas essas coisas.Vector2
,Vector3
eVector4
sem herança efloats
apenas é realmente o padrão de fato nos mecanismos de jogo.typedef float real;
;).Respostas:
Não, não deveria. A única coisa que você estaria usando da herança é o
x
ey
componentes. Os métodos usados em umaVector2
classe não seriam úteis em umaVector3
classe, provavelmente usariam argumentos diferentes e executariam operações em um número diferente de variáveis-membro.fonte
Vector3
IS-NOT-AVector2
(por isso não deve herdar), mas umApple
IS-AFruit
(por isso pode herdar). Se você torce a cabeça o suficiente,Vector3
possui um HAS-AVector2
, mas a perda de desempenho e a dificuldade de codificação significa que você escreverá classes completamente separadas paraVector3
eVector2
.Há uma coisa curiosa que você pode fazer com C ++ (você não especificou uma linguagem, e essa resposta é principalmente porque acho bom ver alternativas, embora eu realmente não acredite que isso seja útil na maioria dos casos.)
Usando modelos, você pode fazer algo assim:
e isso pode ser usado assim:
Como eu disse, não acho que isso seja útil e provavelmente complicará sua vida quando você tentar implementar pontos / normalizar / outras coisas e tentar ser genérico com qualquer número de vetores.
fonte
Vector3f v
um pouco mais bloatyVector3<float> v
typedef
distância.Independentemente da velocidade, a primeira pergunta que você deve fazer a si mesmo ao fazer uma herança é se vai usá-las polimorficamente. Mais especificamente, existe alguma situação em que você pode se ver usando a
Vector3
como se fosse umVector2
(que, herdando dela, está explicitamente dizendo que um vetor3 "é-um" vetor2).Caso contrário, você não deve usar herança. Você não deve usar herança para compartilhar código. É para isso que servem os componentes e funções externas, não que você esteja compartilhando qualquer código entre eles de qualquer maneira.
Dito isto, você pode querer maneiras fáceis de converter
Vector3
s paraVector2
s e, nesse caso, pode escrever uma sobrecarga de operador que truncará implicitamente oVector3
para aVector2
. Mas você não deve herdar.fonte
Vector2
mas herdar de uma baseVector<N>
? Isso faz todo o sentido. Além disso, por que herança significa automaticamente comportamento polimórfico? Uma das melhores coisas do C ++ é que você pode ter uma herança de custo zero. Não há necessidade de adicionar quaisquer métodos virtuais (incluindo destruidores virtuais) na base deVector<N>
classe.Não, já que todos os métodos também precisam ser substituídos, você não poderá herdar dele.
Se alguma coisa, ambos poderiam implementar uma interface Vector. No entanto, como você provavelmente não deseja adicionar / sub / dot / dst entre um Vector2 e Vector3, isso terá efeitos colaterais indesejados. E ter parâmetros diferentes, etc., seria um aborrecimento.
Então, eu realmente não consigo ver nenhum profissional de herança / interface neste caso.
Um exemplo é a estrutura Libgdx, onde Vector2 e Vector3 não têm nada a ver um com o outro, além de ter o mesmo tipo de métodos.
fonte
Se você planeja usar matrizes SIMD, provavelmente é o melhor. Se você ainda deseja sobrecarregar o operador, considere usar uma interface / mixin para acessar a matriz subjacente - por exemplo, aqui está um ponto de partida que possui apenas o (não testado)
Add
.Observe como eu não forneci
X
/Y
/Z
, cadaVectorX
classe herdaria diretamente dessa - pelas mesmas razões especificadas por outras pessoas. Ainda assim, eu vi matrizes usadas como vetores muitas vezes na natureza.Isenção de responsabilidade: Meu C ++ pode ser uma droga, já faz um tempo desde que eu o usei.
fonte
_aligned_malloc
significa que o bug que eu abri não é realmente um bug?__m128
registro, mas_mm_loadu_ps
sim usar . Uma classe boa amostra é aqui em "vectorclass.zip"_mm_loadu_ps
deve funcionar para você com essa estrutura (onde_mm_load_ps
não será). Também adicionei sua sugestão - fique à vontade para editar a pergunta se achar que estou latindo na árvore errada (já faz um tempo desde que usei C [++]).Outro golpe sério em ter o Vec3 herdado do Vec2 ou, sem dúvida, em herdar os dois de uma única classe Vector: seu código estará fazendo muitode operações em vetores, geralmente em situações críticas, e é de seu interesse garantir que todas essas operações sejam o mais rápidas possível - muito mais do que é para muitos outros objetos que não são tão universal ou de baixo nível. Enquanto um bom compilador fará o possível para aplanar qualquer sobrecarga de herança, você continuará confiando mais no compilador do que gostaria; em vez disso, eu os construíria como estruturas com o mínimo de sobrecarga possível e possivelmente tentaria e faria com que a maioria das funções que as usassem (com exceção de coisas como operador + que realmente não podem ser ajudadas) fossem globais em vez de métodos no struct. Geralmente, a otimização antecipada é recomendada contra, e por um excelente motivo,
fonte