Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 派生自同一类但不共享公共方法的两个对象的类设计_C++_Oop - Fatal编程技术网

C++ 派生自同一类但不共享公共方法的两个对象的类设计

C++ 派生自同一类但不共享公共方法的两个对象的类设计,c++,oop,C++,Oop,我有一组类,它们表示字体格式在文件中的存储。每个字体定义一组字形(映射到UTF32代码的形状) 字形可以由轮廓(在我的例子中是一组贝塞尔曲线)或位图表示 我的第一个想法是,这将导致GlyphOutline和GlyphBitmap类继承自Glyph 这种设计的唯一问题是没有通用的方法。为了对这两个类做任何有用的事情,我需要使用rtti(我更愿意避免使用rtti) 我的问题是:你能想出一个更好的方式来表示一个glyph/是否有一些设计模式来处理这种情况 我试图使这种语言不可知,但如果C++有任何区别

我有一组类,它们表示字体格式在文件中的存储。每个字体定义一组字形(映射到UTF32代码的形状)

字形可以由轮廓(在我的例子中是一组贝塞尔曲线)或位图表示

我的第一个想法是,这将导致GlyphOutline和GlyphBitmap类继承自Glyph

这种设计的唯一问题是没有通用的方法。为了对这两个类做任何有用的事情,我需要使用rtti(我更愿意避免使用rtti)

我的问题是:你能想出一个更好的方式来表示一个glyph/是否有一些设计模式来处理这种情况

<>我试图使这种语言不可知,但如果C++有任何区别,我就用C++编写。 编辑:

我曾经考虑过使用泛型,其中Glyph包含对一些/许多Glyph表示的引用,其中T是轮廓或位图,或者其他可以用来表示Glyph的东西。实际上,我非常喜欢这个解决方案,因为它解决了轮廓和位图表示的字形问题。然而,它将强制使用rtti

这可能是我选择的解决方法,如果我使用的是C,反射非常好,但是在C++环境中,我在RTTI中工作的是一组非常复杂的宏,我相信你能理解,我很想避免

编辑:

在回答奥利的问题时,我在某一点上同意你的看法,但isa关系(如GlyphOutline中所示,是一个Glyph,可以做Glyph所能做的一切)是存在的,我认为这意味着应该有继承?我不确定这一点,似乎有很好的理由


到目前为止,我首选的解决方案是访问者模式,但这只是一个注释而不是答案,我想再等一会儿,看看是否有其他解决方案出现。

听起来像是
drawOnScreen()
getMetrics()
getCodePoint()等方法
将是多态行为的良好候选。

我投票支持模板和接口!!无法使用继承,因为没有常见行为。我真的不明白为什么你应该避免RTTI,它是语言的一个更好的特性。如果您当前使用RTTI的设计模式解决了为什么要更改的问题?

好吧,如果我理解正确,您可以使用Builder设计模式,如下所示:

可以定义一组图示符。每个Glyph将实现IGlyph接口,该接口将允许字体类的实例访问贝塞尔曲线集

class OutlineGlyph : public IGlyph
class BitmapGlyph : public IGlyph
然后实例化其中的一些,并通过它们的具体接口设置它们中的每一个

OutlineGlyph og;
og.Method(...)
然后应该实例化FontBuilder类

FontBuilder fontBuilder;
fontBuilder.AddGlyph(og);
fontBuilder.AddGlyph(bg);

Font* font = fontBuilder.CompileFont()

你不能在没有继承的情况下在它上面创建模板吗?如果你想使用RTTI,为什么不能使用虚拟成员函数呢?如果我们知道更多关于如何使用
Glyph
实例的知识,这会有所帮助。你没有做多态性,这是。。。奇怪。如果您没有常见的行为,那么从公共基类派生可能没有意义。请查看访问者模式。这可能是避免rtti的一种方法。您肯定应该有一个接口,比如IGlyph,它将由两个类实现。IGlyph将提供将对象视为一组贝塞尔曲线的方法。您可以使用纯抽象基类来实现此目的。在虚拟成员函数上使用RTTI代替多态性只是一个坏主意(c),因为if(dynamic_cast(p))else会使代码杂乱无章。。。与此->某个虚拟方法()相比,更易于维护和阅读。它喜欢人们滥用JAVA中的instanceof,这意味着他们根本不理解虚拟过载的概念。对不起,你的评论的措辞令人困惑。你是说维护性差得多吗?我更愿意看到:this->some_virtual_method(),而不是:if(dynamic_cast(p))els我想我应该多多少少道歉。当然,它比虚拟callBitmapGlyph提供的beizer曲线集更难管理?你的回答暗示了这一点。如果我误解了,请纠正我。很抱歉,我第一次读你的帖子时没有注意到BitmapGlyph和OutlineGlyph有不同的表示形式。无论如何,IGlyph将包括BitmapGlyph和OutlineGlyph通用的方法。例如,绘图代码等这里的要点是,仅通过在单独的工作流阶段将工作与具体对象区分开来,就可以避免使用rtti和访问者模式。我看不出这是如何避免使用这两种模式的。现在如何从示例中的字体指针获取UTF32代码123的位图表示?据我所知,我会收到一个IGlyph*,我不能确定它是否包含没有某种形式rtti的位图。声明字体类的责任列表很重要。也许最好有一个接口IFont。然后,您可以创建一个类BitmapFont,该类实现IFont并提供获取与其关联的位图的功能。我同意,但这并不能真正解决区分位图图示符和轮廓图示符的问题。回顾我提出的问题,我在编写代码方面稍微不太差,我现在认为这个答案应该让我走上正确的轨道。我只是不明白你当时在开什么车。谢谢