Wrong virtual function called?

closed account (10oTURfi)
I have Object* which was new'd to Enemy. When I call object->Interact(Window, player) code crashes. I did logging and it appears that wrong function is called, likely = 0 one. Is that possible?

Compiled with MSVC++ 2010

This is code cut to very minimum:
1
2
3
4
5
struct Object
{
    virtual void Draw(sf::RenderWindow& Window) = 0;
    virtual int Interact(sf::RenderWindow& Window, Player& player) = 0;
};


1
2
3
4
5
class Creature : public Object
{
    virtual void Draw(sf::RenderWindow& Window) = 0;
    virtual int Interact(sf::RenderWindow& Window, Player& player) = 0;
};


1
2
3
4
5
6
7
8
9
10
11
struct RandomEnemy : Creature
{
    virtual void Draw(sf::RenderWindow& Window) {}
    virtual int Interact(sf::RenderWindow& Window, Player& player);
};

struct Enemy : RandomEnemy
{
    virtual void Draw(sf::RenderWindow& Window);
    virtual int Interact(sf::RenderWindow& Window, Player& player);
};
Last edited on
Is the object pointer still pointing to what you think it should be? Does it crash -> here? If it is pointing to something, dynamic cast it to enemy and see if it becomes null, if it does, there is your problem.
Last edited on
Try checking if the pointer is null first.

if (object)
object->Interact(Window, player)
else
cout << "object is not valid";

Also make sure you are not trying to to call a non virtual method from the base class. In that case you will get a compile-time binding and so the comiler will look at the base class for that method. In that case you need to use a dynamic cast.

I would recommend making a handle class that wraps around tha entire hierarchy and handles all of the pointers and dynamic casting so you when you use it you only need to use . notation.

This is just advice for after u solve this problem though. lol
Last edited on
closed account (10oTURfi)
I can't cast it because at compile time I do not really know if its Enemy*, Vendor*, QuestGiver* or whatever, because i've got std::Map<Coord, Object*>. However, at runtime I notice that it will only crash when I interact with enemies (RandomEnemy* works too)

After some logging I noticed that all Enemy* automagically become NULL when I need them, but before that, they are all fine. Which doesn't make any sense to me because I don't touch them at all.

This code adds the enemies into std::map of Object* :
1
2
3
4
5
6
7
File.open(Original + "Enemies.txt");
        while(File >> ID >> Atk >> Def >> HP >> Level >> Name >> Wealth >> x >> y >> CreatureMapTexture >> Combat)
        {
            Maps[Path].ObjectGrid[y][x] = OBJECT; //Y and X axis inversed on purpose, this is fine
            Maps[Path].Objects[Coord(x, y)] = new Enemy(ID, x, y, Atk, Def, HP, Level, SetSpaces(Name), Wealth, CreatureMapTexture, Combat);
        }
        File.close();


Then when there is something on the Grid (Player is about to interact with Object) This is called:
Maps[PathToMap].Objects[Coord(player.GetX()+x, player.GetY()+y)]->Interact(Window, player)
If I check that pointer right before this is called, i see that pointer is null even though I'm 100% sure that there has to be something in std::map that that specific key value (player collided with something)
Last edited on
Is your Coord using integer or floating point coordinates? If you are using floating points you can easily get rounding errors so using them as key values is not such a good idea.
closed account (10oTURfi)
Coord is 2 integer struct:
1
2
3
4
5
6
7
8
9
10
11
struct Coord
{
    Coord(int x, int y) : x(x), y(y) 
    {}
    int x;
    int y;
    bool operator<(const Coord &coord) const
    {
        return ((x < coord.x) || (y < coord.y));
    }
};
Your operator< is incorrect. It doesn't give strict weak ordering which std::map requires.
Last edited on
Peter87 said the exact answer.

Something like:
1
2
3
4
5
6
 bool operator<(const Coord &coord) const
    {
        if( x < coord.x) return true;
        if( x == coord.x && y < coord.y) return true;
        return false;
    }
closed account (10oTURfi)
Aaah now I see where the problem was with my operator<. Thanks!
Topic archived. No new replies allowed.