0

I have code like following

class GameObject
{
public:
    virtual void update(...) = 0;
    virtual void render(...) = 0;
};

class Sprite : public GameObject
{
public:

    Sprite();
   ~Sprite()
    {

    }

    void setSrcRect()noexcept
    {
       //Some code
    }

    void setDstRect()noexcept
    {
       //Some code
    }

    uint32_t getWidth() const noexcept { return width_; }
    uint32_t getHeight() const noexcept { return height_; }

    virtual void update(...) override
    {
        //Some code
    }

    virtual void render(...) override
    {
       //Some code
    }
};

Later on I create Object like

GameObject* obj = new Sprite();

problem is that I am not able to call methods like

obj->getWidth();

I can add those methods in GameObject but I want to keep it pure interface. Only having pure virtual methods. I am keeping GameObject like this because it will give me advantage when later on in game I have more objects.

I can just store them

std::vector<GameObject*> actors;

in render I can do

 for(const auto actor: actors)
 {
   actor->render();
 }

Also as currently sprite is there could be one more GameObject SpriteSheet and so on. What I can do to achieve this? Keep GameObject as it is but add methods to classes inherited from it.

I do understand that type of sprite is still GameObject and method calls can only be resolved at runtime. So I am requesting for any alternative methods to achieve this?

  • You are assigning the `Sprite` object to a `GameObject` pointer which does not implement `getWidth()`. Read about object slicing. https://stackoverflow.com/questions/274626/what-is-object-slicing You have to make `getWidth()` as a virtual function in `GameObject`. – Richard Jan 14 '19 at 02:30
  • What do you expect to happen if at the point `obj->getWidth()` gets called, `obj` is not a `Sprite`? – Sam Varshavchik Jan 14 '19 at 02:32
  • I know here object slicing will happen. I have written that at end of my question. Hence I am asking any way to avoid this slicing from happening? – Paritosh Kulkarni Jan 14 '19 at 14:27

1 Answers1

1

Use dynamic_cast:

auto sprite_game_obj = dynamic_cast<Sprite*>(obj);
if(sprite_game_obj) sprite_game_obj->getWidth()

or the shorter

dynamic_cast<Sprite*>(obj)->getWidth()

Here's a sample code snippet to show it in usage.

tangy
  • 3,056
  • 2
  • 25
  • 42
  • Thanks this looks like one for the way of doing it.I think it will check for derived base type relation if we do dynamic casting So its safe to cast like this. Hmmm Thanks. – Paritosh Kulkarni Jan 14 '19 at 14:28
  • in case the solution works for you - could you consider approving it – tangy Jan 14 '19 at 15:29