0

I am developing some tree of inheritances that represents the 3D objects in my rendering engine.

My 3D models can be either static or animated. You can move (translate), rotate or scale both of them, but only animated 3D models have bones attached (so they deform in the way bones moves).

My first though was to create such hierarchy:

//#1:
Model3D <|-- ModelStatic
Model3D <|-- ModelAnimated

On the other hand, you can look on it as: we have an Model3D class and some of such models can be animated:

//#2:
Model3D (=ModelStatic) <|-- ModelAnimated

The 3D models are just for an example. The same problem keeps re-appearing over and over again in any hierarchy.

The question is: when should I use #1 approach and when should I go for #2? What benefits and what disadvantages those two concepts provide?

So far I came up with those:

#1:

pros:

  • Static and Animated Models can inherit some methods from common type (move, rotate, scale).

contras:

  • Most of the methods Static and Animated Models will inherit, will have to be re-written anyway, for both of them separately (due to cache, optimizations etc., they store their data / members in a different way).

#2:

pros:

  • We always know that if we get a Model3D, we can treat it at least like Static Model (in #1, when we get Model3D it can be Animated and we cannot use it with assumption it's a Static Model, some cast / check would be needed).

contras:

  • Long naming convention (e.g. for Animated and Static Sprites, it would be SpriteStatic instead of just "Sprite" and so on).

Which approach looks more natural? Hardly speaking, I don't know - they both describe the problem.

In other words

In other words: Animated Model enchants Static one or rather both Animated and Static are two types of Models?

PolGraphic
  • 3,233
  • 11
  • 51
  • 108

1 Answers1

0

This is a bit subjective depending on your precise specifics. However as a general rule just avoid inheriting from concrete base classes, which leaves us with option 1. For example see why derive from a concrete class is a poor design for a bit of detail.

From that question Or, as Scott Meyers puts it in Item 33 of More Effective C++,[8] "Make non-leaf classes abstract."

The short version is that having concrete base classes makes it easier to accidentally slice off your child object, use arrays incorrectly. An abstract base class just provides an interface. Remember that you should inherit to substitute, NOT to reuse code! And keep in mind that just because a base class is abstract doesn't mean that it can't have its own common state with corresponding non-virtual methods to operate on that state.

Community
  • 1
  • 1
Mark B
  • 95,107
  • 10
  • 109
  • 188
  • Hm, interesting point, thank you. Still - I though that "abstract" means "purely virtual". At least in C++, when you e.g. want to get equivalent for interface from Java, you make an abstract (=purely virtual) class which has none non-virtual methods. – PolGraphic Nov 18 '14 at 17:29