peo*_*oro 9 c++ double-dispatch visitor-pattern
我知道访客模式是什么以及如何使用它; 这个问题是不是这个的副本一个.
我有一个库,我把大部分可重复使用的代码放在我写的,并链接到我的大多数项目.
我经常需要为某些类添加功能,但不将这些新功能添加到库中.让我用一个真实的例子:
在这个lib中,我有一个类Shape,继承自CircleShape,PolygonShape和CompositeShape.
我现在正在开发一个图形应用程序,我需要渲染它们Shape,但不想render在核心Shape类中放置虚函数,因为我使用的一些项目Shape不进行任何渲染,而其他图形项目可以使用不同的渲染引擎(我在这个项目中使用Qt,但对于我使用OpenGL的游戏,因此该render函数需要不同的实现).
最着名的方法是使用访客模式,当然,这会让我心中产生一些疑问:
任何类的任何库都需要像我Shape一样扩展.大多数公共图书馆(大约所有公共图书馆)都没有为访客模式提供任何支持; 为什么?我为什么要?
访问者模式是一种在C++中模拟Double Dispatching的方法.它在C++中不是原生的,需要显式实现,使得类接口更复杂:我认为applyVisitor函数不应该与我的类函数处于同一级别,我认为这就像打破抽象.
明确的向上铸造Shape用dynamic_cast比较昂贵,但对我来说,它看起来像一个清晰的解决方案.
所以我该怎么做?在我的所有库类中实现Double Dispatching?如果图书馆提供的Shape不是我的,但在互联网上找到了一些GPL库怎么办?
sbi*_*sbi 14
首先:"访问者模式是一种模拟C++中双重调度的方法." 这是,呃,不完全正确.实际上,双调度是多调度的一种形式,这是一种在C++中模拟(缺失)多方法的方法.
是否应通过添加虚函数或添加访问者来实现类层次结构上的操作取决于添加类与添加操作的概率:
是的,许多图书馆没有访问者界面.
当我们只看上面的推理时,如果类的数量经常变化,那就是正确的.也就是说,如果经常发布库,并且不断添加新类,那么提供访问者界面就没有多大意义,因为每次新版本带来新类时,使用该库的每个人都需要调整所有访问者.因此,如果我们只看上面的推理,那么如果lib的类层次结构中的类数很少或永远不会改变,那么访问者界面似乎才有用.
但是,对于第三方库,还有另一个方面:通常,用户无法更改库中的类.也就是说,如果他们需要添加一个操作,他们可以做到这一点的唯一方法就是添加一个访问者 - 如果库为他们提供了插入它的钩子.
因此,如果您正在编写库并且感觉用户应该能够向其添加操作,那么您需要提供一种方法让他们将访问者插入您的lib.