If I follow, you are trying to define a class Warrior
, that can be Human or Orc, but should inherit of the class in question.
If that is what you want to do, the correct way to go about it is to write a generic Warrior
class:
template<typename Race>
class Warrior : public Race
{
// Warrior attributes & methods
};
By doing this, you will be able to instanciate human warriors (Warrior<Human>
) as well as orc warriors (Warrior<Orc>
), or warriors from any other race.
However, Warrior<Human>
and Warrior<Orc>
will be considered as totally different classes, which do not belong to the same inheritance tree.
Now, maybe that is not what you want to do. Maybe you want to be able to manipulate containers like vector<Warrior*>
to handle both human and orc warriors indicriminately and make use of polymorphism. In this case, it may make sense to reverse the inheritance and to have a template class Human<Class>
that inherits from Class
.
But what if you want to also be able to manipulate containers like vector<Human*>
? Well, in this case, you want to handle characters polymorphically with regard to their race or class, so it should inherit from both!
template<typename Race, typename Class>
class Character : public Race, public Class
{
// Character attributes & methods
};
Then you can safely have an inheritance tree for character classes and one for races.
Then again, if you want to be able to manipulate things like vector<Character*>
to handle all characters at once, that won't do. The simplest thing would be to create a class AbstractCharacter
, from which all characters would inherit. But what if, while you're at it, you want your characters to be able to change class? Then you have to change your design: maybe your character is not a human that is also a warrior, but a character that has a race that is 'human' and a class that is 'warrior'.
In this case, make race and class attributes of your character:
class Character
{
Race* characterRace;
Class* characterClass;
// Character attributes & methods
};
where Race
and Class
are the roots of the inheritance trees of races and classes respectively. And you will still be able to use polymorphism.
(Note: although I wrote it like this for more readibility, it would be better to use smart pointers instead of regular pointers in the actual implementation)
Edit: when I talk about changing the class of the character, I mean at runtime. And that also means that you can create a character of the class and race you want at runtime rather simply.