仅通过从其他类继承类型来定义类型
Defining a type only by its inheritance from other classes
我正在SFML中实现一个可视化树。SFML 包含两个重要的绘图类:sf::Drawable
和 sf::Transformable
。如果这些捆绑在一起会很好,但它们不是。许多对象继承自两者,即:
class SFML_GRAPHICS_API Text : public Drawable, public Transformable
class SFML_GRAPHICS_API Sprite : public Drawable, public Transformable
class SFML_GRAPHICS_API Shape : public Drawable, public Transformable
对于我的可视化树,我有一个继承自 Drawable 和 Transformable 的 SceneNode
类,并且 draw 函数将调用私有 onDraw 本身,然后调用其子级。但是,许多 SFML 本机类(如 sf::Text
)具有私有的绘制函数。所以,我不能创建一个这样的类
class Text: public sf::Text, public SceneNode
然后将其放入可视化树中。对于这些本机类,我无论如何都不需要它们来绘制子类,我只是希望能够将它们作为叶节点添加到可视化树中。问题的症结在于可视化树的每个成员都需要从sf::Drawable
继承和sf::Tranformable
。我需要能够定义一个继承自这两者的类型。如果我定义虚拟类
class LeafNode: public sf::Drawable, public sf::Tranformable { }
这似乎定义了我想要的类型。然后,SceneNode
将包含std::vector<LeafNode*> m_children
.在绘制这些子项时,我将对每个项目进行动态转换,以查看它是否是SceneNode
,然后调用绘制函数,以便SceneNode
绘制其子项。
但是,由于类型不兼容,以下代码无法编译:
LeafNode * node = new sf::Text("PLAY", font, 20);
理想情况下,我想定义类似的东西
std::vector<sf::Drawable, sf::Transformable*> m_children
其中,这种虚构的语法意味着每个元素都必须从sf::Drawable
和sf::Transformable
派生。这可能吗?
但是,许多 SFML 本机类(如 sf::Text)具有私有的绘制函数
。
这并不完全正确。由于sf::Drawable::draw
功能受到保护,因此sf::Text
draw
方法也受到保护。这是C++的复杂规则之一。
所以,我不能创建一个这样的类
class Text: public sf::Text, public SceneNode
如果这样做,层次结构中将有两个sf::Drawable
和sf::Transformable
基类,一个来自sf::Text
,一个来自SceneNode
。那就不好了。
绘制这些子项时,我将对每个项目进行动态投射,以查看它是否是 SceneNode,然后调用绘制函数,以便 SceneNode 绘制其子项。
我不推荐这样的设计。使用dynamic_cast通常表明您的软件设计不是那么好。(我不想在这个话题上离题太多,谷歌关于这个话题。
但是,让我们回答您的基本问题:
其中,这种虚构的语法意味着每个元素都必须从 sf::D rawable 和 sf::Transformable 派生。这可能吗?
不。但无论如何,你可以做更简单的事情。
与其让Text
从sf::Text
和SceneNode
继承,不如将类定义为包装器。它可以像这样简单:
class Text : public SceneNode {
sf::Text m_text;
public:
sf::Text& get() { return m_text; }
// Override SceneNode drawing method:
virtual void onDraw(RenderTarget& target) const
// Draw m_text:
target.draw(m_text);
}
};
不过,这个快速包装器有两个缺陷。它不使用SceneNode
的可转换部分。b) 由于封装被get()
破坏,因此用户可修改两个可转换的:一个来自SceneNode
,一个来自sf::Text
。
对于 a),当您修复 b) 时,修复应该很简单。要修复 b),您必须使包装器稍微复杂一点:而不是这个丑陋的get()
,编写方法来设置未链接到sf::Transformable
的底层sf::Text
的属性,例如 setColor
.
在对 SMFL 一无所知的情况下(它可能提供更好的解决方案),我认为您可以实现这个向量。您只需要定义自己的指针包装器,它只接受指向从多个类型继承的对象的指针:
template <class T1, class T2>
struct special_pointer_wrapper
{
T1* t1;
T2* t2;
template<class T>
special_pointer_wrapper(T* p)
: t1(dynamic_cast<T1*>(p))
, t2(dynamic_cast<T2*>(p))
{
if ((p1==0) || (p2==0))
throw "Error";
}
getT1 T1* () const { return t1; }
getT2 T2* () const { return t2; }
};
此类接受任何指针,并确保其指向的类型派生自 T1 和 T2(即使它们看起来完全不相关)。如果它不是派生对象,则抛出。通过函数getT1()
和getT2()
,您可以访问指向两个基类的指针。
请注意,由于dynamic_cast
构造可能很慢,但类型的提取为 O(1)。
- 继承模板类中的类型别名
- 在运行时检查继承是否只有一种类型和 void*
- C++从外部类继承的嵌套类;不允许使用不完整的类型
- 可以从std::string继承以提供类型一致性吗
- 事件系统:使用类型转换或联合进行继承
- 继承类中的 C++ 成员变量类型重写
- C :可以从类及其受保护的成员类型继承可以继承吗?
- 模板类上的类型继承
- C 类从类型继承
- 在 C++11 中,从私有嵌套类型继承是否合法?
- 模板基类型继承
- C#中从指定类型继承的模板类的等效项是什么
- 为boost mpl列表中的每种类型继承容器
- 从基类和返回类型继承模板
- 从基元类型继承的枚举
- 使用类型继承的数字组的层次结构
- 在任何/某些C++编译器中是否有允许从本机(基本)类型继承的选项
- 创建从不同对象提供的类型继承的类的对象
- c++用这个类作为类型继承类模板
- 我如何从mpl::vector中的所有类型继承