Multiple Inheritance vs. Composition

Started by
3 comments, last by krippy2k8 11 years, 6 months ago
I'm curious to know if other developers think multiple inheritance is bad practice and if composition should be used instead or if it's a case of "the right tool for the job". The question came about as I recently started work on my entity system again and have found myself with an entity class that has grown inheriting 4 other objects - most times I've only ever needed single inheritance. In my mind this doesn't seem too bad in terms of what is being inherited but I thought I'd just see what others have to say and perhaps improve on my design/skills.

My entity class at its most basic:


class Entity : public ComponentContainer, public PropertyContainer, public Serializable, public NetworkObject
{
public:
};


Basically an entity contains a list of components and properties, can be serialized and is networked. I suppose I could use composition and have the ComponentContainer and PropertyContainer as members of an Entity instead, but I found it more practical to be able to do the following:


entity.AddComponent<MyComponent>();


The Serializable and NetworkObject objects allow the Entity to implement it's own logic for file de/serialization , etc and for network de/serialization. A Component object also inherits these objects.
Advertisement

Basically an entity contains a list of components and properties, can be serialized and is networked. I suppose I could use composition and have the ComponentContainer and PropertyContainer as members of an Entity instead, but I found it more practical to be able to do the following:

Then an Entity HAS a component container and property container, so it ISN'T component and property container.
Then I don't think Entity should inherit from them.

"The Serializable and NetworkObject objects allow the Entity to implement it's own logic for file de/serialization".
That sound like Serializable and NetworkObject are interfaces, then it's fine Entity implements them via inheritance.

https://www.kbasm.com -- My personal website

https://github.com/wqking/eventpp  eventpp -- C++ library for event dispatcher and callback list

https://github.com/cpgf/cpgf  cpgf library -- free C++ open source library for reflection, serialization, script binding, callbacks, and meta data for OpenGL Box2D, SFML and Irrlicht.

Agreed with that....

Unless ComponentContainer and PropertyContainer are also interfaces that it implements. In that case it IS A container and the container has components, rather than HAS A container.

I've seen that type of component container inheritance work well in practice. It means you don't need to re-implement the container logic and otherwise do some nifty things.
I kind of agree with you but for practicality sake I chose to inherit Component/Property containers because an entity is a collection of components and properties. It doesn't re-implement the methods of the containers (though it could but isn't necessary). I figured it'd be better than having wrap all the collection methods ie:


class Entity : public Serializable, public NetworkObject
{
public:

void AddComponent(Component* c) { components.AddComponent©; }

private:
ComponentContainer components;
};

Entity e;
e.AddComponent(...);
Personally I would argue that both approaches are bad practice for an entity system. An entity in a pure entity system should neither "be" nor "contain" a collection of components, it is merely an identifier that is used to associate components with each other. All of your components (which should just be data) should be stored in a database that is keyed by the entity identifier, then your various systems query the database for the required components. Using an entity class that contains the components makes it difficult to obtain the performance advantages of a pure entity system.

That being said, given only your 2 choices I would definitely go with composition. If anything just inherit from NetworkObject. It seems conceivable to me that NetworkObjects can also be property containers and also be serializable. If they are not already that is a big potential design complication that could raise it's head in the future.

An entity system by it's very nature is supposed to be all about composition and avoiding the rigidity of OOP, so making the system itself so heavily dependent on inheritance seems pretty backwards to me.

This topic is closed to new replies.

Advertisement