I was just experimenting with interfaces and wrapping classes and I have come across a roadblock. I am wrapping an SFML::RenderWindow in a class that implements a draw() function. For example:
struct ISprite {
....
functions for sprites...
....
}
class SFML_Sprite : public ISprite
{
public:
....
functions implementing stuff for sprites
....
private:
sf::Sprite mSprite;
}
struct IWindow {
...
virtual void draw(const ISprite& sprite) = 0;
...
}
class SFML_Window : public IWindow
{
public:
...
void draw(const ISprite& sprite)
{
//This is where the problem is. Is there a way for me to get to
//mSprite?
mWin.draw(sprite.mSprite);
}
private:
sf::RenderWindow mWin;
}
In other words, is there a way for me to pass the underlying stuff around? A pattern I am missing? I am basically trying to hide the windows and sprite implementations. Eventually, I would like to try 'swapping' implementations and go a little lower level, but if I can't figure this out, I am no where near ready to try that.
Thanks!
Why don't you want to do the cast? It's safe and well defined in this context:
class ISprite {
};
class SFML_Sprite : public ISprite
{
};
class IWindow {
public:
virtual void draw(const ISprite& sprite) = 0;
};
class SFML_Window : public IWindow
{
public:
void draw(const ISprite& _sprite)
{
auto sprite = static_cast<const SFML_Sprite&>(_sprite);
}
};
int main() {
SFML_Window i;
IWindow &a = i;
SFML_Sprite x;
ISprite &y = x;
a.draw(y);
return 0;
}
You can use dynamic_cast if you want to pay for a runtime check to ensure you're really getting the right type, but you always should be as you're not going to be mixing two different graphics backends in the same code.