包装 API 时,我是否应该避免在实现类中进行向上转换
Should I avoid upcasting in implementation classes when wrapping an API
我正在编写一些 c++ 代码,并希望将 SFML 用于我的 GUI 实现。我尝试编写一个纯虚拟 GUI 类以及一些相关类,例如用于绘制的 Surface,而不是公开内部类型。然后,我在 SFML 中为每个实现。我的问题是GUI的draw(Surface s)函数需要访问SFML类型sf::Texture,我需要从我的Surface对象访问该类型。
现在,我知道我的代码中的任何 Surface 都将使用与 GUI 类相同的 API,因为我只有一个实现。我正在尝试编写好的代码,因为这主要是一个学习练习,我相信这将打破 Liskov 替换原则。
我试图在下面尽可能简单的代码中概述我的问题:
class Surface {
// ...
};
class SFML_Surface : public Surface {
public:
sf::Texture* get_texture() {
return _surface->getTexture();
}
// ...
private:
sf::RenderTexture* _surface;
};
class GUI {
public:
virtual void render(Surface *s) = 0;
// ...
};
class SFML_GUI : public GUI {
public:
void render(Surface *s) {
SFML_Surface *surface = static_cast<SFML_Surface*>(s);
if(surface == 0)
return;
this->_window->render(surface->getTexture());
}
};
我对从这里开始有点茫然,我想不出一种明显的方法来解决类间依赖关系,而无需在某些部分进行投射。
我将不胜感激对上述代码的任何想法,或对替代方法的讨论。或者,正如标题所问的那样,在这种特定情况下,抛弃是一个坏主意吗?
提前谢谢。
代码编辑:dynamic_cast应该是一个static_cast
class Surface {
// ...
virtual TextureBase* get_texture() = 0;
};
class SFML_Surface : public Surface {
public:
sf::Texture* get_texture() { // define sf::Texture to inherit from Texture Base
return _surface->getTexture();
}
// ...
private:
sf::RenderTexture* _surface;
};
这个想法是返回类型不需要相同,只要它与原始返回类型共变即可。
相关文章:
- 为 Sql 服务器实现 odbc 包装器.将数据库数据读取为字符或要求驱动程序将数据转换为 C 类型
- 独立于实现的浮点/整数转换
- 在调用函数上实现C++转换
- 实现可以<T>转换为 Stream 的 Stream,<U>其中 U 是 T 的基数
- 如何实现相互强制转换
- 是否可以实现自动全局转换
- 如何将 std::array<double, 100> 转换为 std::array<float, 100> ?(避免明显的样板实现)
- 无法在 IOS 中将常量字符 * 表[] 转换为 NSArray 以实现统一
- 转换为链接切割树的C 实现
- 在没有 const 强制转换的链表中实现高级方法
- 如何将 GLCM 的实现转换为 Java C++
- 优先级队列实现为单一链接,无法更新插入的指针转换
- 了解C++位操作中的二进制转换实现
- std::tuple的实现是否允许在触发空类元素的派生到基转换时失败
- 如何为涉及对象成员、间接寻址和强制转换的排序算法实现lambda函数
- 高效的无符号到签名转换,避免实现定义的行为
- 如何在Python中实现ITK映像和SimpleItk图像之间的转换
- 智能指针实现的隐式强制转换
- 如何将表驱动的 CRC 实现转换为按位实现
- 使用DirectX视频加速(DXVA)实现媒体基础转换(MFT)