Brad
Brad

Reputation: 10650

Casting Derived class to base class

I have a tricky little problem I have run into. I believe the problem has to do with the way I am casting things.

So I have a base class called combatEntity. It has the following function

class combatEntity {
public:
    virtual void update();
};

I then have a class mob, which is derived from combatEntity, overrides the update function:

class mob : public combatEntity {
public:
    virtual void update();

}

I then have a class named monster, which is derived from mob and also overrides the update function.

class monster: public mob {
public:
    virtual void update();
}

I have a combatEntity pointer called i:

combatEntity* i;

Then I have:

//returns a mob* pointer (needs explicit cast)
monster* newMonster = getMob();
i = newMonster;

The getMob() function:

mob* getMob() {
   mob* newMob = new mob();
   //set some data in newMob
   return newMob;
}

When I call i->update(), it calls mob::update(), because newMonster is set to "new mob();", since getMob() returns a new mob pointer. When I call i->update(), I need it to call monster::update(), but using breakpoints, I see it is calling mob::update() and not monster::update().

so I need to create a new monster object, but still have it's base class data filled with the object returned from getMob(), but have the functions overridden properly. I have also tried dynamic_cast, static_cast and reinterpret_cast, and none seem to work. Or I need to cast my base class to a derived class, while properly overriding functions with the derived class.

Hopefully this makes sence. Any advice would be appreciated.

Upvotes: 0

Views: 7402

Answers (3)

PaperBirdMaster
PaperBirdMaster

Reputation: 13320

take a look to your hierarchy tree, make sure the classes are related how you think.

This code

#include <iostream>

struct combatEntity
{
    virtual void Update() { std::cout << "Combat Entity\n"; };
};

struct mob : combatEntity
{
    virtual void Update() { std::cout << "Mob\n"; };
};

struct monster : mob
{
    virtual void Update() { std::cout << "Monster\n"; };
};

int main(int argc, char **argv)
{
    combatEntity *ce = new monster;
    ce->Update();
    delete ce;

    return 0;
}

creates this output:

Monster

Source: http://ideone.com/k6LAB

Upvotes: 2

Christian Stieber
Christian Stieber

Reputation: 12496

Well, since you're using virtual, "update" will always call the correct function, no matter what you declare the pointer to be. That's just how "virtual" works.

If you want your pointers to determine what gets called, rather than the object themselves, make the stuff non-virtual. In this case, the pointer-type will determine which "update" is getting called.

If you want both, you can still call something like monster::update() instead of just update. However, unless you're doing this from inside a derived class' update function (to invoke the superclass implementation), trying to get past the inheritance hierarchy may be a sign of bad design.

Upvotes: 0

Walter
Walter

Reputation: 45414

Your line

monster* newMonster = getMob();

should not compile. I get

error: invalid conversion from ‘mob*’ to ‘monster*’ [-fpermissive]

(also your line i = monster; should presumably read i = newMonster;). This explains it all, I think (see also comment from Luchian).

Upvotes: 0

Related Questions