2012-07-17 17 views
7

¿El único punto para implementar el segundo caso es si deseo derivar de un colisionable sin ser un objeto? Si ese es el caso, ¿cuándo es el primer caso favorable desde que el segundo caso ofrece más flexibilidad?¿Qué tipo de herencia es más preferible?

Ambos colisionables tienen solo una función virtual pura y Object es una clase base para los objetos que se pueden dibujar en la pantalla (en mi caso).

^Suponiendo que estoy entendiendo el siguiente código correctamente (no estoy muy seguro de TBH)

class Object 
class CollidableObject : Object 
class Actor : public CollidableObject 

class Object 
class Collidable 
class Actor : public Object, public Collidable 

Editar:

Sobre la base de Matt/Seth

class Object 
class Collidable 
class Clickable 
class Trackable 
class BlowUppable 
class Actor : public Object, public Collidable, public Clickable, public Trackable, 
       public BlowUppable 

class SomeObjectThatIsTakenForGrantedThatEverythingElseIsInherited : public Actor 

Primer ejemplo es el segundo caso y el segundo ejemplo es el primer caso. Supongo que ese es el único uso que veo para el primer caso.

@Luchian
Esta va a ser una pregunta diferente a la original ya que su respuesta no fue ninguna de las dos.

En este caso, ¿hay alguna diferencia al cambiar un objeto de una relación is-a a has-a? En cada caso, para verificar colisiones, un objeto debe tener una bandera para saber si se debe verificar la colisión. En su caso, el miembro se puede verificar si es nulo o no, pero en el caso derivado, el objeto mismo dice si puede colisionar o no. En una matriz/árbol, puedo pasar el objeto derivado como argumento o pasar el hitbox como argumento usando un método get().

estar más en profundidad, tengo otra clase - usando el segundo caso

class Hitbox : public Object, public Collidable 

y la clase de actor tiene como miembro

class Actor : public Object 
{ 
    Hitbox *box; 
}; 

objetos que tienen colisión tendría un Hitbox en su lugar y esto representa su publicación con precisión, creo. Pero lo que me sigue dando es que cuando reviso tu ejemplo de nuevo, ¿significa que Hitbox debería tener un miembro de Collidable en su lugar?

class Hitbox 
{ 
    Collidable *collision; 
}; 

Lo que tengo:
Un actor posee una Hitbox que se ocupa de la colisión

Lo Hitbox debe hacer:
Heredar Collidable o
Tienes Collidable como miembro

Actor ya está siguiendo tu convención. ¿Hitbox debería hacer lo mismo?

Respuesta

2

Haría el segundo caso, ya que Object y Collidable son preocupaciones transversales. Si vas por la ruta CollidableObject, probablemente terminarás con una explosión combinatoria de clases. No pasará mucho tiempo hasta que vea un CollidableTrackableClickableBlowuppableObject.

Dado que Collidable es puramente virtual, se utiliza en este caso como interfaz, por lo que no tiene muchas de las críticas que argumentan en contra de la herencia múltiple. Simplemente indica que un Actor implementa la interfaz Collidable.

+0

No tendría que tener un 'CollsableTrackableClickableBlowuppableObject' si lo hizo primero; simplemente sería una clase heredada de 'Collidable',' Trackable', 'Clickable' y' Blowuppable', como la primera, pero no heredarías 'Object' como la primera. No estoy seguro si el primero es más útil; ¿no debería dibujarse todo 'clicable' en la pantalla? Si los tiene todos separados, no puede decir si se puede hacer clic en su 'Objeto' o si su' Clickable' es dibujable. Con la segunda forma, sabes que 'Clickable' es dibujable. –

+1

No tendrías que tener un ... si hicieras el _segundo_ que quise decir. –

1

Este es un escenario perfecto para el strategy pattern. Aquí es donde el idioma inglés juega trucos en nuestras mentes y nos hace pensar que CollidableObject es un objeto válido para tener en esta jerarquía. Yo digo que la colisión es más un comportamiento que un objeto, así que no iría con ninguno de los dos.

Prefiero composición para esto:

class Object 
{ 
    CollidableBehavior* collisionBehavior; 
} 
class Actor : Object 
{ 
    // collisionBehavior = new ActorCollision() 
} 

class AClassThatDoesntCollide 
{ 
    // collisionBehavior = NULL 
} 
+0

Si el comportamiento de colisión depende de los detalles de la clase Actor, esto no será muy práctico. Por otro lado, si se trata de un atributo independiente, tiene sentido. –

0

es el único punto en la aplicación del segundo caso es si quiero derivar de un Collidable sin ser un objeto?

Sí, el segundo caso le da más flexibilidad ya que permite separar las interfaces. Por ejemplo, más tarde es posible que desee un objeto que se pueda colgar, pero que no sea dibujable.

Cuando es el primer caso siempre favorable ya que el segundo caso ofrece más flexibilidad .

El segundo caso ofrece más flexibilidad pero también es más complejo de diseñar. Al final, necesitarás herencia virtual y esto es más difícil de manejar. Sin embargo, si sus clases base son puramente abstractas, no debería ser un problema.

Puede ver this.

Cuestiones relacionadas