wh1t3crayon wrote: |
---|
//but the parameters aren't even used in this Base implemetation!
I'm not sure how sloppy the above method is, so I'm really just asking for other ideas for design patterns. |
Hi,
I don't think that matters: part of the idea of an ordinary virtual function is to define behaviour (once) that applies to all it's derived classes. For example:
1 2 3
|
virtual void CAnimal::Speak() { // CAnimal class is abstract, or at least has a protected ctor
std::cout << m_Noise << '\n'; // m_Noise is std::string & each derived class has this member variable
}
|
This means we don't have
CowSpeak()
,
DuckSpeak()
, or
DogSpeak()
functions.
Hopefully your Base class is abstract, or has a
protected
or
private
constructor - so that one cannot create an instance of it.
Yeah I'm casting a couple of different times already, such as casting in the main game loop to find the correct Player* so I can process the keyboard's input and pass it to the Player*. Also, my current design from earlier with the Attack() problem is that I'm simply casting the passed object into an NPC*, and if it's valid then I lower its health. |
I still don't see the need for that either. With a container (or function accepting) of Base pointer/s, we have already established that they are actually derived pointers, it's just that they are declared as base pointers.
All the compiler does is check whether Derived really is derived from Base. This feature allows one to declare the signature for a function once, then either define the function once with an ordinary virtual function, or specialise the function as many times as required in each derived class (from a pure virtual function declaration)
So there are a couple of things that can happen when using a pointer to call a function:
- If the Derived class has a function with the same name as the function being called, it calls that function. That's easy - the pointer is to the derived object.
- If not, then the compiler works it's way up the inheritance tree until if finds a virtual function with that name, and calls it instead, otherwise it's an error.
The other complication is if one has overloaded functions, but the rules are the same whether the function is virtual or not.
Note we are not actually doing anything
to the Base class, we shouldn't be able to - because it should be abstract.
So with
Player*
, a function could be declared to take a pointer to Player, or indeed something higher up like Actor (parent of Player and Enemy) or even GameObject (from which everything derives from). Then the function is called with a pointer to
JamesBond
or whatever as an argument, the compiler does the right thing - no need for casting.
I agree with
firedraco , a
RecieveAttack
function is a good idea.
BTW, what does NPC stand for?
I know your code was a quick example, I am sure you know that one should not have public member variables like
health
. Something like a function called
AdjustHealth
instead.
I also notice you have virtual inheritance, this goes hand in hand with multiple inheritance - is that what you have?
Hopefully this all helps a bit :+)