class Spell
{
protected:
//some variables here
};
class Spell_A : public Spell
{
protected:
//some variables here
public:
//this spell grows a tree at the given position
void activate_spell(int position_x, int position_y);
};
class Spell_B : public Spell
{
protected:
//some variables here
public:
//this spell damages a person
void activate_spell(Person* pointer);
};
class Spell_C : public Spell
{
protected:
//some variables here
public:
//this spell turns a rock into a golem
void activate_spell(Rock* pointer);
};
Spell should have an activate_spell() function declared something like virtualvoid activate_spell(/*parameters*/)=0;
In order for this to work, all derived classes have to implement activate_spell(). Oh, and all versions of the function have to take the exact same parameters and return the same type.
By the way, "to polymorph" isn't a word. The closest expression would be "to make X polymorphic".
Polymorphism requires that all derived classes have a shared interface. This is so functions from derived classes can be called using pointers to the base class without run time type information.
For example:
class Base{
public:
virtual ~Base();
virtualvoid foobar(int)=0;
};
class DerivedA:Base{
public:
~DerivedA();
void foobar(int);
};
class DerivedB:Base{
public:
~DerivedB();
void foobar(int);
};
int main(){
std::vector<Base *> v;
v.push_back(new DerivedA);
v.push_back(new DerivedB);
v.push_back(new DerivedA);
v.push_back(new DerivedA);
for (int a=0;a<v.size();a++)
v[a]->foobar(a); //No casting or type check needed
}
If this requirement can't be met, the class structure can't be made polymorphic. At least not AFAIK.
In your case, you could do it by having the base class function take all the parameters, then each of the derived classes will use the parameters as they need.
That is true; AFAIK virtuals must all have the same parameter list.
Basically, you call the virtual through a pointer or reference to a base-class item.
That reference could point to a base class or it could point to an object of derived class. Both are legal because the pointer will only refer to the "base-class" subsection of the derived object. It is legal for this to remain undetermined at compile time. The compiler will then generate code that will differentiate which version of the virtual to call, based on the actual item to which you are referring/pointing, at runtime. This is what is known as polymorphic behaviour. (IF I am right and that is one big if.)
And here's something I've noticed that I must ask about: Why is it that so many examples refer to foo, bar or the predominant combination thereof, foobar?
So to do what you'd want to do, OP, you would have to:
A) Make all those activate_spells use the same set of arguments.
B) (At least this is what I would do) Define a PURE virtual called activate_spell with the desired argument list in the base class Spell. A pure virtual's declaration is followed by =0 virtualvoid foobar(int) = 0;
and cannot be called. It is created solely so that inheritees will (must, if they intend to use it at all) be able to redefine the function. However the function itself does not exist. In addition, this will turn Spell into an abstract class. Objects of an abstract class cannot be declared (although their derivations can, and those derivations will contain the appropriate subobjects).
C) Create a pointer or reference to a Spell (I believe this is still legal despite the abstractness of Spell, due to the fact that it could point to a concrete derivation, someone could check) and bind it to an object of a class derived from spell.
D) Referring to that reference as though it were the class object in question, call the virtual with the desired arguments.
And now, in step D, the compiler would call the virtual matching the actual (dynamic) type of the class object pointed to.
But it has been a while since I studied my polymorphic behaviors.