【问题标题】:How would you hand a member of a class implementing an interface to another class using the interface?您如何将实现接口的类的成员交给使用该接口的另一个类?
【发布时间】:2026-02-06 19:15:01
【问题描述】:

我只是在试验接口和包装类,但遇到了障碍。我将 SFML::RenderWindow 包装在一个实现 draw() 函数的类中。例如:

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;
}

换句话说,有没有办法让我传递底层的东西?我缺少的模式?我基本上是在尝试隐藏窗口和精灵实现。最终,我想尝试“交换”实现并降低一点水平,但如果我无法解决这个问题,我还没有准备好尝试。

谢谢!

【问题讨论】:

  • 哦 - 我试图避免强制转换。我认为这可能有效,尚未检查,但如果可以的话,我希望不必这样做......
  • Isprite 是否有名为 mSprite 的成员?
  • 我可能敢说继承是不适合这项工作的工具。 IWindow 说它适用于各种精灵,所以SFML_Window : IWindow 也承诺它适用于各种精灵。但它看起来不像它。也许您应该使用模板:template<typename Sprite> struct IWindow { ... }; class SMFL_Window : public IWindow<SFML_Sprite> { ... };
  • @cigien - 不 - 它没有。我只是想说明这就是我想要达到的目标。我正在尝试将 sfml 位“隐藏”在包装器或接口中,以便最终更改实现
  • @HTNW 我能够通过使 SFML_Window::draw 成为 SFML_Sprite 的朋友并使用 static_cast 来使其工作: mWindow.draw(static_cast<:sfml_sprite>(&sprite)-> mSprite);但这感觉很不对劲。我会试试模板的想法。

标签: c++ inheritance interface encapsulation


【解决方案1】:

你为什么不想做演员?在这种情况下,它是安全且定义明确的:

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;
}

如果您想为运行时检查付费以确保您确实获得了正确的类型,您可以使用 dynamic_cast,但您始终应该这样做,因为您不会在同一代码中混合两个不同的图形后端。

【讨论】:

  • 很大程度上是因为它“感觉不对”,但在这种情况下,它可能还可以。最终,我想用我自己的代码进行实验,从 xcb、opengl 制作窗口,然后升级到 vulkan 等——然后我会编写这样的代码,这样就不需要强制转换了,因为这会比 sfml 低一两个级别.我还想尝试编写共享库来交换功能,而渲染是我认为它既有用又有趣的一种情况。谢谢!