C++ : multiple inheritance & casting

Started by
2 comments, last by markypooch 9 years, 4 months ago

I was wondering if I shouldn't start using multiple inheritance for my classes, but I don't have any experience with it. Imagine something like this:

struct GraphicalObject;

struct PhysicalObject;

struct StaticObject : public PhysicalObject;

struct DynamicObject : public PhysicalObject;

struct Particle : public GraphicalObject;

struct Box : public GraphicalObject, public DynamicObject;

void render (GraphicalObject* obj);

void applyImpulse (DynamiclObject* obj);

void setCollisionFilter (PhysicalObject* obj);

Of course, I can pass a particle to render, but can I pass a box to any of the functions just like that?

And what if I want to store pointers? Like this:

vector<PhysicalObject*> v;

Can I simply put box objects there?...

Advertisement
Thats a typical, but bad idea. The rigid inheritance structure will give you problems when you need one aspect of a class without another thats already inherited, causing code duplication or bloated objects or objects with deactivated parts.
You better just have independent components like Position, BoundingBox, Mesh for graphics and others with data for the game logic. Then you can combine these as needed through composition into game objects or just have some arrays of these components, depending on your needs.
Game entities can be: cameras, lights, actors, model instances, vehicles, helicopters, planes, etc.
Game object components can be: springs, wind sources, models, physical objects – good candidates for external libraries resources.

This is how you can create a helicopter:

Extend from model instance and attach a wind source to the helicopter.

This is how you can create a player:

Extend from model instance and attach a camera to it. When you move the player in the game state, the camera follows its path.

This is basically the difference between component and entity.

The component is just an wrapper for the resource you have externally and an entity is the container – is what gets mapped to the component; the ID.


Of course, I can pass a particle to render, but can I pass a box to any of the functions just like that?


A box – not really the shape of the box, but instead a class that can instantiate the box shape – knows how to apply impulse on itself. You just need to call:

PhysicalObject::AddForce( const Vector3& _vForce );


And what if I want to store pointers? Like this:

vector v;

Can I simply put box objects there?...

*>

Not really the shape of the box, but instead a class that can instantiate the box shape. Why load multiple boxes shape data when you can load once and share that?!

I'd do like that:

CBox inherits from CShape;
CPhysicalObject inherits from CShapeInstance;
CShapeInstance has a pointer to CShape and a matrix that defines where to be rendered – doesn't mean it can render itself;

Then you have std::vector <CPhysicalObject*> in the physics world.

The rigid inheritance structure will give you problems when you need one aspect of a class without another thats already inherited, causing code duplication or bloated objects or objects with deactivated parts.

Wintertime is correct,

For instance, in your provided code, struct Box is not only going to inherit those two parent structure's (public GraphicalObject, public DynamicObject) but also whatever parents those structures inherit (A no-brainer of course but with multiple inheritance this can make things baloon fast). Also, member encapsulation is gone since these are structures and all of their members have by default public access modifiers. Meaning through struct Box one will be able to call all of the inherited and implicintly inherited struct's variables and Methods.

-Marcus

This topic is closed to new replies.

Advertisement