Sign in to follow this  

Inheritance : Multiple function calls (implicit)

This topic is 4399 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I have a base class, ACTOR, and derived from it, ACTOR_MOVER. Derived from ACTOR_MOVER is ACTOR_PLAYER. ACTOR_MOVER has a function, Update, which updates any movement-related variables within the actor. ACTOR_PLAYER is also going to have an Update function, which I need to implicitly call ACTOR_MOVER's Update in the process. This way I can call ACTOR::Update, and have the code for both MOVER and PLAYER called, if the ACTOR* happens to be an ACTOR_PLAYER. Is this possible? Thanks, Kris

Share this post


Link to post
Share on other sites

class ACTOR {
public:
virtual ~ACTOR();
virtual void Update(void);
};

class ACTOR_MOVER : public ACTOR {
public:
virtual void Update(void) {
// do stuff
}
};

class ACTOR_PLAYER : public ACTOR_MOVER {
public:
virtual void Update(void) {
ACTOR_MOVER::Update();
// do other stuff
}
};

Share this post


Link to post
Share on other sites
Quote:
Original post by Kris_A
Hi,
I have a base class, ACTOR, and derived from it, ACTOR_MOVER. Derived from ACTOR_MOVER is ACTOR_PLAYER. ACTOR_MOVER has a function, Update, which updates any movement-related variables within the actor.

ACTOR_PLAYER is also going to have an Update function, which I need to implicitly call ACTOR_MOVER's Update in the process. This way I can call ACTOR::Update, and have the code for both MOVER and PLAYER called, if the ACTOR* happens to be an ACTOR_PLAYER. Is this possible?

Thanks,
Kris


language? in the two i know, java and c++, polymorphic methods must explicitly invoke the method in any super classes.

so you will have to add



class SomeClass : public SomeOtherClass
{
public:
virtual void update()
{
SomeOtherClass::update();
//do SomeClass specific updating here...
}
};



good luck!

EDIT: 3 minutes behind, *sigh*, *shame*

Share this post


Link to post
Share on other sites
Exactly what I needed. Thanks!

Edit: And thanks to rip-off even though I just missed his post

Share this post


Link to post
Share on other sites
The template method pattern (not related to C++ templates!) is a way better idea if you want to enforce that the parent's version is always called:


class base
{
public:
/* NOT virtual! */ void update() { /* do common stuff */ do_update(); }

protected:
virtual void do_update() = 0; // Subclass-specific stuff here!
};

class derived : public base
{
protected:
virtual void do_update { /* do child-specific stuff here! */ }
};

Share this post


Link to post
Share on other sites
Quote:
Original post by Sharlin
The template method pattern (not related to C++ templates!) is a way better idea if you want to enforce that the parent's version is always called:


class base
{
public:
/* NOT virtual! */ void update() { /* do common stuff */ do_update(); }

protected:
virtual void do_update() = 0; // Subclass-specific stuff here!
};

class derived : public base
{
protected:
virtual void do_update { /* do child-specific stuff here! */ }
};


i fail to see how this causes the parents function to always be called, due to polymorphic behaviour and the fact that the parents function is pure virtual this ensures it is never called unless the child explicilty calls it...

Share this post


Link to post
Share on other sites
Because the function in the public interface (update()) is NOT virtual, and is therefore always called in a polymorphic context. In C++, it not having the final keyword, a subclass could of course replace it in static contexts by providing its own implementation, but this is of course as bad a practice as any replacement of a non-virtual function. The subclass-specific stuff is in the (pure virtual) function do_update(). Please refer to any of these, or, of course, to Design Patterns by Gamma et al.

Share this post


Link to post
Share on other sites
Of course the solution you presented doesn't suit the case where it's not the base class' behaviour that needs to be invoked, but the child class' behavior by the grandchild class.

Share this post


Link to post
Share on other sites
or when the base class's function needs to be called after, or sometime during, the child's function.

Share this post


Link to post
Share on other sites
SiCrane:
Oops, yes, didn't read the original question very carefully. My bad; should not be posting to GameDev in the middle of a New Year's party :)

Aface:
Well, after is no big deal, just swap the "do common stuff" and the do_update() call. And about the in between case, many times the subclass-specific stuff can be divided into multiple functions that each do some elementary operation (which is of course how you should always use functions anyway). Like this:

void update()
{
do_first_thing(); // pure virtual calls
// do common stuff
do_second_thing();
// more common stuff here
do_third_thing();
// yet more common stuff
}

This pattern may at first seem unnecessarily limiting of what child classes can do, but it does work very well in quite many cases, and nicely enforces the substitution princible, which is never a bad thing. I'd even argue that non-pure virtual functions are rarely a good idea, and explicitly calling a base class version of a virtual function from a derived class should not often be necessary. YMMV, of course.

Share this post


Link to post
Share on other sites
Sign in to follow this